tests/auto/xmlpatterns/XSLTTODO
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/auto/xmlpatterns/XSLTTODO	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1450 @@
+This is a TODO file for XSL-T 2.0 support.
+
+- LHF:
+    * Warning bug, last parameter is always whined about.
+    * Box in comment/PI/text/ws(?) handling -- pending Matthias
+    * type036 -- namespace on top element isn't copied
+    * XTDE0865
+    * Attend XSLTTokenizer::isXSLT()
+    * Remove redundant set() calls in setFocusHelper().
+
+- Missing features:
+    General                                     Priority
+    ---------------------
+    * 1.0 QXmlQuery::evaluateTo(QIODevice *)    P1 DONE
+    * 1.0 Test suite integration                P1 DONE
+    * 1.0 xsl:key                               P1
+    * 1.0 fn:key()                              P1
+    * 1.0 2.0 Compatibility mode                P1
+    * 1.0 Regular parameters in templates       P1
+    * 1.0 xsl:include                           P1
+    * 1.0 xsl:copy-of                           P1
+    * 1.0 xsl:copy                              P1
+    * 1.0 xsl:import                            P1
+    * 1.0 fn:format-number                      P1
+    * 1.0 xsl:message                           P2
+    * 1.0 fn:current()                          P1 DONE
+    * 2.0 fn:type-available()                   P3 DONE
+    * 2.0 xsl:use-when                          P3
+    * 2.0 fn:unparsed-entity-uri()              P3
+    * 2.0 fn:unparsed-entity-public-id()        P3
+    * 2.0 Tunnel Parameters                     P3
+    * 2.0 xsl:attribute-set                     P3
+    * 1.0 xsl:decimal-format                    P2
+    * 1.0 xmlpatterns: initial template         P1 DONE
+    * 1.0 xsl:number                            P1
+    * 1.0 Complete handling of xsl:sort         P2
+    * 2.0 Grouping
+        - fn:current-group()
+        - fn:grouping-key()
+        - xsl:for-each-group()
+    * 2.0 Regexp
+        - xsl:analyze-string
+        - xsl:matching-substring
+        - xsl:non-matching-substring
+        - fn:regex-group()
+    * 2.0 Date & Time formatting
+        - fn:format-dateTime()
+        - fn:format-date()
+        - fn:format-time()
+
+    Serialization & Output:
+    ----------------------
+    * 1.0 xsl:output
+    --- Tie together serialization. Should we add
+        QXmlQuery::evaluateTo(QIODevice 1.0 const) ?
+    * 2.0 xsl:character-maps
+    * 2.0 xsl:character-map
+    * 2.0 xsl:result-document
+    --- Should the "default output" be handle with xsl:result-document? Would
+        depend on compilation.
+
+Optimizations:
+    * Remove adjacent text node constructors
+    * Remove string-join when first arg's static cardinality is not more than one
+    * Remove string-join when the second arg is statically known to be the empty string.
+    * Remove string-join when the second arg is a single space and the parent is a text node ctor.
+    * Rewrite to operand if operands are one. What about type conversions?
+    * Replace lookups with xml:id with calls on id().
+    * Recognize that a/(b, c) is equal to a/(b | c). The later does selection and node sorting in one step.
+    * Remove LetClause which has empty sequence as return clause, or no variable dependencies at all.
+    * Do a mega test for rewriting /patterns/:
+                    "node() | element()" => element()
+                    "comment() | node()" => comment()
+
+      and so forth. This sometimes happens in poorly written patterns. How does
+      this rewrite affect priority calculation?
+
+Tests:
+    * xml:id
+        - Come on, the stuff needs to be reorganized xml:id.
+        - Read in xml:id document with whitespace in attrs, write the doc out. Attrs should be normalized.
+        - Do lookups of IDs with xml:id attrs containing whitespace.
+
+    * current()
+        - Use current() inside each instruction
+        - In a template pattern
+        - Several invocations: current()/current()/current()
+
+
+    * Diagnosticsts:
+        - See http://www.w3.org/Bugs/Public/show_bug.cgi?id=5643 . Comments
+          should be taken into account when comparing. This suggests that we
+          don't have any test which produces a document with XML comments.
+
+    * element-available()
+        - Review the tests.
+        - Try using declarations in XSL-T, should return false
+        - Use xsl:variable(both instr and decl)
+        - invoke with all the XSL-T instructions.
+        - Should return false for when, otherwise, matching-substring, non-matching-substring, etc?
+        - Supply the namespace in the name via the default namespace, no prefix.
+
+    * unparsed-text()
+        - Load an empty file
+        - Use a fragment in the URI
+        - Use an invalid URI
+        - Use device bindings and a QRC to ensure that we're not using a generic
+          network manager.
+        - Duplicate all the network tests. Same as for doc()
+
+    * unparsed-text-available()
+        - Same as for unparsed-text()
+
+    * Sequence constructor that contains only:
+        - XML comment
+        - whitespace text node
+        - processing instruction
+        - a mix of the three
+
+    * xsl:function
+        - Ensure that it's not it's not in scope for use-when.
+        - xsl:function/xsl:param: use processing instructions, whitespace and comments as child: should be stripped
+        - Use <xsl:function/> : @name missing.
+        - Don't strip ws, and have ws between two xsl:param, and between xsl:function and xsl:param.
+        - Use xsl:function with no body.
+        - use xsl:param/@tunnel = no
+        - use xsl:param/@tunnel = yes
+        - use an invalid value for xsl:param/@tunnel = yes
+        - Have a non-WS text node in xsl:function/xsl:param/
+        - Have a WS text node in xsl:function/xsl:param/
+        - Have a WS text node in xsl:function/xsl:param/ while preserving WS.
+        - use a comment as child of xsl:param
+        - use a PI as child of xsl:param
+        - XTSE0770 with import precedence and all that.
+        - have two identical function in the stylesheet. The last has override=no. Should still report XTSE0770.
+        - have @override with invalid value.
+        - have whitespace inside xsl:param with different strip modes.
+        - Have @select => error
+        - Have body => error
+        - call current() inside body. XPDY0002?
+
+    * Does xml:base/StaticBaseURI and StaticCompatiblityStore prevent proper
+          type checking due to expectedOperandTypes() returns item()*?
+
+    * xsl:template/xsl:param
+        - Have @required=yes, and have @select => error
+        - Have @required=yes, and have body => error
+        - Have a variable reference in a template after another, which has
+          param, to ensure they aren't in scope.
+
+    * xsl:template/@match
+        - Have a pattern with unions, and have a body which relies on its
+          static type.
+
+    * @version:
+        Have @version on *all* attributes.
+
+    * xsl:call-template
+        - Have a variable reference just after a xsl:call-template which has
+          with-param, to ensure they aren't in scope.
+        - Have an xsl:with-param which isn't used in the template. Error?
+        - Have an xsl:with-param that has a type error.
+        - an xsl:with-param is not in scope for the next one. Test this => error.
+        - Have a call:template, whose with-param computes its value by calling
+          another template, while using an with-param too.
+
+    * XQuery:
+        - DONE Ensure namespace {expr} {expr} is flagged as invalid
+        - Use all XSL-T functions: error. Or we do that already?
+        - Ensure order by collation 1 + 1 is an error
+        - Ensure order by collation {1 + 1} is an error
+
+    * document()
+        - Basic node deduplication, no test exists for that.
+
+    * xsl:perform-sort
+        - Have no xsl:sort. Error. Must be at least one.
+        - have xsl:sort with invalid value.
+        - sort atomic values.
+        - Trigger "The stable attribute is permitted only on the first xsl:sort  element within a sort key specification"
+        - have xsl:sort with no select and no seq ctor.
+        - trigger the delegated queueing. All instructions inside.. xsl:sort?
+        - have multiple sort statements, with the last being <xsl:sort/> only.
+        - have WS between xsl:sort that is not ignorable.
+        - Use a variable reference whose name is equal to our synthetic name. This should be XPST0008, but probably isn't.
+        - Have an invalid value in xsl:sort/order. Use space
+        - have xsl:sort return numbers, but data-type specify string.
+        - have an AVT in xsl:sort/@lang
+        - have an AVT in xsl:sort/@case-order
+        - have an AVT in xsl:sort/@data-type
+        - have an AVT in xsl:sort/@stable
+        - Have mixed result, and hence incorrectly trigger  XPTY0018 which the code currently raise.
+        - Depend on the context position inside xsl:sort, when being child of
+          perform-sort. Currently we create singleton focuses(I think), while
+          we want the focus to be over the whole input sequence, not on indivual items.
+        - Have <xsl:perform-sort select="valid-expr"/>: xsl:sort is missing
+        - Use current() in the xsl:sort and the body, to ensure the right scope is picked up
+
+    * xsl:copy-of
+        - Have a text node. It's not allowed.
+        - Have PIs, comments, and ignorable whitespace as children. Sigh.
+
+    * xsl:namespace
+        - Use xsl:fallback.
+        - Use xsl:namespace inside xsl:variable and introspec the result in various
+          ways. This is a big area, we don't have namespace nodes in XQuery. Yes, calling evaluateSingleton() will probably crash.
+        - Use no select and no body, error: XTSE0910
+        - Have name expression evaluate to the empty sequence.
+
+    * Sequence ctor that:
+        - Has invalid element in XSL namespace. E.g, xsl:foo
+
+    * xsl:import
+        - Have element as child as xsl:import: disallowed.
+        - Have text as child as xsl:import: disallowed.
+        - Have PIs and comments as child as xsl:import: allowed.
+
+    * xsl:include
+        - Have element as child as xsl:include: disallowed.
+        - Have text as child as xsl:include: disallowed.
+        - Have PIs and comments as child as xsl:include: allowed.
+
+    * xsl:strip-space
+        - Have PIs, comments, whitespace as child.
+
+    * xsl:element
+        - Extract EBV from result.
+        - Use space in validation element.
+
+    * xsl:perform-sort
+        - Have PIs and comments in between xsl:sort elements.
+
+    * xml:space
+        - We never pop our stack. Fix the bug, and ensure we have tests for it.
+
+    * fn:unparsed-entity-uri
+        - Check type of return value
+        - Do basic unparsed-entity-uri("does-not-exist")
+
+    * fn:unparsed-entity-public-id
+        - Do basic unparsed-entity-uri("does-not-exist"), two permutations, check the spec
+
+    * xsl:element
+        - Use disallowed attribute: select
+        - use unknown type in @type
+        - Use @namespace, but be not in the lexical space of xs:anyURI
+        - use disallowed enumeration in @validation
+        - have a name expression that evaluates to a xs:QName value as opposed to a string.
+        - have a name expression that evaluates to a xs:QName value as opposed to a string. but
+          also have the namespace attribute
+
+    * xsl:attribute
+        - Use disallowed attribute: match
+        - use unknown type in @type
+        - Use @namespace, but be not in the lexical space of xs:anyURI
+        - use disallowed enumeration in @validation
+        - have a name expression that evaluates to a xs:QName value as opposed to a string.
+        - have a name expression that evaluates to a xs:QName value as opposed to a string. but
+          also have the namespace attribute
+
+    * xsl:template
+        - Use the union keyword, it's forbidden, only "|" is allowed
+        - Use an expression other than Literal and VarRef in KeyValue[8]
+        - use a function other than key().
+        - have a declaration that only can apperar as a child of xsl:stylesheet.
+        - Have an element in the XSL-T namespace, but which is invalid, e.g "bar"
+        - Use an axis other than child or attribute in pattern.
+        - Have a template that no no match and no name attribute.,  XTSE0500
+        - use child::document-node() in pattern
+        - use @foo/child in pattern
+        - apply templates to parentless attributes.
+        - Have 3e3 in @priority
+        - Have a @match with more than two alternatives, e.g "a | b | c", and have them all actually matching.
+        - Use an XML name in the mode so we trigger
+          NCNameConstructor::validateTargetName()
+        - A template which only has a non-WS text node.
+        - A template with param, followed by text node.
+
+    * Simplified stylesheet
+        - Use @version attribute only on doc element. Should fail, since @{XSL-T]version must be present
+
+    * fn:current()
+        - Have <xsl:value-of select="current()"/>
+
+    * xsl:variable have a variable reference appearing before its global declaration, and then somehow trigger recursion.
+    * xsl:choose
+        - elements/nodes intermixed with xsl:choose/xsl:when
+        - invalid attribute on xsl:choose
+        - invalid attribute on xsl:when
+        - invalid attribute on xsl:otherwise
+        - invalid attribute on xsl:if
+        - invalid attribute on xsl:template
+        - invalid attribute on xsl:stylesheet
+        - invalid attribute on xsl:transform
+        - xsl:otherwise in the middle between xsl:when elements.
+        - use namespace declarations on xsl:when
+        - use namespace declarations on xsl:otherwise
+        - use namespace declarations on xsl:choose
+
+    * Namespaces:
+        - Have:
+            <xsl:sequence xmlns:bar="http://example.com/" select="1"/>
+            <xsl:sequence select="bar:foo()"/>
+
+    * XPath
+        - For each XQuery-specific expression, add a test using that expression:
+            - typeswitch
+            - let
+            - validate
+            - extension expression
+            - unordered
+            - ordered
+            - for
+            - computed text node constructor
+            - computed attribute constructor
+            - computed comment constructor
+            - computed PI constructor
+            - computed element constructor
+            - computed document constructor
+            - direct element constructor
+            - direct comment constructor
+            - direct PI constructor
+            - all declarations
+
+        - Use all the predefined prefixes in XQuery; non are in XSL-T.
+
+    * xsl:when
+        - Use xml:space on it
+
+    * xsl:otherwise
+        - Use xml:space on it
+
+    * xsl:version
+        - Use letters, XTSE0110
+        - Use a float: 2e3, XTSE0110
+        - Use a weird number, 2.00000001
+
+    * xsl:document
+        - use disallowed attribute: select.
+        - use unknown type in @type
+        - use disallowed enumeration in @validation
+        - What happens if the type in @type is unknown?
+        - Use xml:base attr and check URI.
+
+    * xsl:sequence
+        - use match attribute
+
+    * xsl:stylesheet
+        - Use @xsl:default-collation on xsl:stylesheet. Shouldn't have any effect. Or?
+        - Use an XSL-T instruction as child -- invalid.
+        - Have an element in the XSL-T namespace, but which is invalid, e.g "foo"
+        - Have xsl:default-collation="http://example.com/" on xsl:stylesheet
+        - Use prefix local: in say a function name. Not allowed.
+        - Use comments after document element.
+        - XTSE0010: <xsl:invalid version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
+        - Change the version with @xsl:version on all elements that we have.
+
+    * Patterns.
+        - Basic */* test:
+            <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="*/*"><xsl:sequence select="'MATCH'"/></xsl:template>
+
+
+</xsl:stylesheet>
+
+        - Basic a/b test:
+            <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="a/b"><xsl:sequence select="'MATCH'"/></xsl:template>
+
+
+</xsl:stylesheet>
+    * xsl:strip-whitespace
+        - Use a namespace prefix which is not unboudn
+        - have a syntax error in one of the node tests
+
+    * xsl:preserve-whitespace
+        - Use a namespace prefix which is not unboudn
+        - have a syntax error in one of the node tests
+
+    * xsl:value-of
+        - select attribute, and comment in body(error, XTSE0870)
+        - select attribute, and processing instruction in body(error, XTSE0870)
+        - select attribute, and CCDATA in body(error, XTSE0870)
+        - select attribute, and element in body(error, XTSE0870)
+        - use xsl:sequence in body. Default separator should be none.
+        - use match attribute
+        - use double apostrophes/quotes. How are they dealt with?
+
+    * xsl:apply-templates
+        - use match attribute
+        - apply in a mode for which no templates are declared
+        - apply in a mode which is mispelled for another.
+        - Have: <xsl:apply-templates select="id('id2')/a | id('id5')"/>
+          We CRASH
+
+    * xsl:for-each
+        - No body: <xsl:for-each select="abc"/>
+        - No select attribute: <xsl:for-each>text</xsl:for-each>
+        - Have mixed result, and hence incorrectly trigger  XPTY0018 which the code currently raise.
+        - Have:
+            <xsl:for-each select="1, 'asd'">
+                <xsl:sequence select="."/>
+            </xsl:for-each>
+
+    * xsl:variable
+        - Test that function conversion rules are invoked
+        - For what is an xsl:variable in scope? Where does the spec state it? Test
+          that it is not in scope where applicable.
+        - Have: <variable name="a" select=""/>
+
+    * xsl:text
+        - count the result of a template that has text node(non-ws),
+          xsl:text(content), xsl:content(zero content), text node(non-ws
+        - Have an element inside xsl:text: XTSE0010.
+        - Use comments and PIs intermixed with text inside.
+
+    * xsl:for-each
+        - use match attribute
+        - What should this produce? Saxon produces "123" but with xsl:text removed, "1 2 3".
+                <xsl:template match="/">
+                    <xsl:for-each select="1 to 3">
+                        <xsl:sequence select="."/>
+                        <xsl:text></xsl:text>
+                    </xsl:for-each>
+                </xsl:template>
+
+    * xsl:if
+        - Have <xsl:if test="">body</xsl:if>. Error
+        - Have <xsl:if test="valid-test"/>. That is, empty body.
+
+    * xsl:sequence
+        - select attribute missing: <xsl:sequence/>
+        - content other than xsl:fallback, e.g text node.
+        - How do we sort?
+
+    * for every state for XSL-T parsing:
+        - Use invalid element that is in the XSL-T namespace.
+
+    * In all cases expressions are queued/generated:
+        - Trigger expression precedence bugs, due to lack of paranteses.
+
+    * Use xml:space in stylsheeet that doesn't have value preserve nor default.
+    * For each case we have while(!reader.atEnd()):
+        - test that triggers parser error and that we detect it properly.
+
+    * for every element that allows text:
+        * Use CDATA. QXmlStreamReader distinguishes between the two. text before and after.:wa
+        * Use XML Comments and split up text nodes.
+
+    * Patterns:
+        * Ensure node() doesn't match document nodes().
+        * "//" is an invalid pattern
+        * Is there some expression which has no children? findAxisStep()
+        * Use @*/asdo
+        * XPST0003: key(concat("abc", "def"), "abc")
+        * XPST0003: id(concat("abc", "def"))
+        * XPST0003: concat('abc', 'def') // WILL CRASH
+        * XPST0003: unknownFunction()
+        * Use double: key("abc", 3e3)
+        * Use three argument key() in pattern.
+
+    * Simplified stylsheet modules:
+        * Omit the xsl:version attribute. XTSE0010
+
+    * type-available()
+        * We have no tests at all?
+
+    * have xml:base on the following elements and check them with
+      static-base-uri():
+        - all instructions
+        - all declarations, eg:
+        - xsl:choose, xsl:choice, xsl:otherwise
+        - xsl:template
+        - xsl:function
+        - etc
+
+    Embedded stylesheet modules
+        - Verify that we don't choke on xsl attrs with invalid attributes outside;
+          "In an embedded stylesheet module, standard attributes appearing on
+          ancestors of the outermost element of the stylesheet module have no effect."
+
+    Parsing:
+        - Error message for:
+                <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+                    <xsl:template match="/">
+                        <e/>
+                </xsl:stylesheet>
+        - Use the document "<do/" as focus.
+        - Write a test for each call to checkForParseError();
+
+
+    function-available:
+        - Generally low coverage it seems.
+
+
+<xsl:template match="/"/>                   <!-- t0 -->
+<xsl:template match="*"/>                   <!-- t1 -->
+<xsl:template match="asd"/>                 <!-- t2 -->
+<xsl:template match="comment()"/>           <!-- t3 -->
+<xsl:template match="a/b"/>                 <!-- t4 -->
+
+<xsl:apply-templates select="*"/>
+
+
+*(
+((/)/call-template(t0))
+(*/call-template(t1))
+(element(asd)/call-template(t2))
+(comment()/call-template(t3))
+(a/b/call-template(t3))
+)
+
+==>
+
+*/typeswitch(.)
+  case $g0 as document-root()   return call-template(t0)
+  case $g0 as element()         return call-template(t1)
+  case $g0 as element(asd)      return call-template(t2)
+  case $g0 as comment()         return (call-template(t3)
+  case $g0 as a/b               return (call-template(t4)
+
+
+Patterns are used in:
+    - xsl:for-each-group/@group-starting-with
+    - xsl:key/@match
+    - xsl:number/(@count, @from)
+    - xsl:template/@match
+
+
+
+c/b
+=>
+child-or-self::element(b)[parent::element(c)]
+
+c/b/a
+=>
+child-or-self::element(a)[parent::element(b)[parent::element(c)]]
+
+d/c/b/a
+=>
+child-or-self::element(a)[parent::element(b)[parent::element(c)[parent::element(d)]]]
+
+
+
+-----------------------------------
+    <xsl:apply-templates select="foo"/>
+                   =>
+
+    child::element(foo) map apply-template(#default)
+-----------------------------------
+
+-----------------------------------
+    <xsl:apply-templates mode="yo" select="foo">
+        <xsl:sort select="@bar"/>
+    </xsl:apply-templates>
+                   =>
+
+    let $g0 := for $g1 in child::element(foo)
+               order by @bar
+               return $g1
+    return apply-template(yo)
+-----------------------------------
+
+-----------------------------------
+<xsl:perform-sort select="$in">
+    <xsl:sort select="@sortKey"/>
+</xsl:perform-sort>
+
+        =>
+
+sort $in/order by @sortKey
+-----------------------------------
+
+
+-----------
+
+John Snelson of Oracle Berkeley DB XML & XQilla writes in private mail:
+
+	I'd had the same thought myself, too - you must be reading my mind ;-)
+
+What is he referring to?
+
+If one spends some time on fancy diagrams, QtXmlPatterns[LINK]'s, the XQuery
+engine that shipped in Qt 4.4, architecture looks like this:
+
+
+Recently I've started implementing XSL-T 2.0(hopefully to be done for Qt 4.5)
+and the whole approach to this is modifying the existing codebase as follows:
+
+
+
+
+
+
+Put differently, when QtXmlPatterns is dealing with XSL-T stylesheets, it
+replaces the XQuery tokenizer with a tokenizer which translates the
+stylesheet into XQuery tokens, that is consumed by the existing XQuery
+parser, extended with both grammar non-terminals and tokens to accomodate the
+XSL-T features that XQuery doesn't have. In compiler terms, it can be seen as
+an "extreme" frontend. Not only is the same intermediate representation used,
+the grammar is too.
+
+What is the point of this?
+
+The functional overlaps XQuery, XSL-T and others as well have is of course
+widely established. Even the specifications are at times generated from the
+same source documents, and that implementations subsequently modularize code
+is of course second nature to any engineer, and seen to some degree or
+another in contemporary implementations. Typically this happens in a
+traditional fashion, classes are re-used, their functionality widened to
+cover both/more languages. However, I believe doing it directly on the
+grammar level introduce several advantages.
+
+The parser is based on Bison and since it's not running in the experimental
+pull mode, it uninterruptedly calls the tokenizer. The tokenizer, class
+XSLTTokenizer, in turns calls an pull-based XML parser: QXmlStreamReader.
+What often complicate in ocassions like this is who that gets the right to
+call who, and who gets the convenience of tracking state in a natural way
+through a call stack.
+
+XSLTTokenizer is conveniently implemented: as it encounters declarations and
+instructions in the stylsheet, it recursively descends in the XSL-T grammar
+through its own functions, adding tokens to a queue, which is delivered to
+the parser when asked -- and when the queue is empty it resumes queuing
+tokens. The tokenizer is fairly crude, it queues up tokens for instructions
+uninterrupted, and only have states between declarations. Hence,
+XSLTTokenizer queues up tokens for each template and function body, but
+enters "delivery mode" inbetween. This of course periodically breaks
+streaming since it's buffering up tokens, but considering that the memory
+usage for tokens is low and that a finer granularity for states(say, being
+able to pop the stacks when being inbetween two xsl:when elements) requires a
+significant effort, this is fine until proven otherwise.
+
+
+Advantages
+---------------
+discuss analysis.
+
+
+XSLTTokenizer rewrite XSL-T to XQuery as follows:'
+
+Instructions
+-------------
+xsl:if An if/then/else expression whose else branch is the empty sequence
+
+xsl:choose: again, a nesting of if/then/else expressions
+
+xsl:value-of: a computed text node constructor. Its body contains a call to
+string-join() involving the separator attribute
+
+xsl:variable: a let/return binding. Since XSL-T is statement-like in its
+sequence constructors, parantheses are used to ensure the variable binding is
+in-scope for all subsequent statements.
+
+for-each: it is the iteration/mapping mechanism XQuery fails to supply,
+despite path steps and the FLWOR machinery. for-each iterates using a
+focus(which for doesn't, but paths do), but can do so over atomic values and
+unconditionally without sorting the result by document order(which paths
+can't/doesn't, but for do). For implementations that normalize paths into for
+loops as the formal semantics do, the approach is straight forward. In
+QtXmlPatterns' case, a synthetic token is queued which signals to create
+a "relaxed" path expression which skips halting on atomic values in its
+operands(XPTY0019) and also skips node sorting.
+
+All "direct" node constructors, like <myElement/>, and "computed" node
+constructors, like xsl:element, are all rewritten into the corresponding
+XQuery computed node constructors. In some cases direct node constructors
+could have been used, but in anycase the IR yielded is the same, and that
+computed constructors happen to use less tokens.
+
+A particular case is xsl:namespace, an instruction which doesn't have any
+corresponding expression in XQuery. In the case of QtXmlPatterns, the code
+obvious already have a notion of "create this namespace on this element", and
+an AST node was trivially added for fetching the namespace components
+computationally. However, the introduction of xsl:namespace in an XQuery
+implementation is not to be taken lightly wrt. to for instance testing, since
+it introduces a new node type.
+
+perform-sort: surprisingly this expression of all complicate matters, for the
+simple reason that its operands occur in the opposite order compared to
+XQuery when the input sequence is supplied through a sequence constructor,
+hence breaking the streamed approach. XSLTokenizer solves this by
+buffer: the attributes of the xsl:perform-sort elements are stored,
+the xsl:sort elements queued onto a temporary queue, and subsequently is
+either the select attribute or the sequence constructor queued, and the
+tokens for xsl:sort appended afterwards. This complicated code greatly, since
+XSLTokenizer had to be able to "move around" sequences of tokens.
+
+In addition perform-sort has the same problem as for-each, the iteration
+mechanism falls inbetween paths and the for loop. The focus for perform-sort
+is also the focus for the sequence constructor and the select attribute, but
+the focus for the xsl:sort elements is the initial sequence. This is
+approached by having a for loop, and where the expression in each order by
+clause has a relaxed path expression whose left operand is a variable
+reference to what the for loop bound.
+TODO Doesn't work. Focus size wrong.
+
+This is an approach that implementations of the "second generation" of the
+technologies can take. The bif difference is that XSL-T 2.0 doesn't have the
+restrictions of 1.0, more evident in XQuery's syntax.
+
+xsl:sort XSL-T is much more dynamic than XQuery through the use of templates,
+but also
+because more decisions can be taken at runtime through all attribute value
+templates. xsl:sort is surely a good example of this with its AVTs for
+language, order, collation, stability and what not. XQuery's order by stands
+in strong contrast, which has these coded in the grammar. In QtXmlPatterns'
+case, the AST node corresponding to order by was generalized to take things
+such as stability and order from operands. This is paid by the code paths in
+XQuery since for them are constants generated and inserted as operands even
+though its known at compile time what is needed. However, considering that
+these evaluations are not inside the actual sort loop, but instead only
+computed on each sort invocation, it shouldn't be too bad.
+
+xsl:message
+
+Templates
+-------------------------
+
+A big bucket of questions for an XQuery implementation is of course the
+introduction of templates. In this case it is too of large interest to
+rewrite relevant code into primitive XQuery expressions.
+
+Templates' drawback is often mentioned to be their dynamic nature which makes
+static inferences hard or impossible. However, by again rewriting in clever
+ways and making the code visible in a standard way, existing analysis code
+can operate upon it.
+
+For the purposes of this discussion, templates can be broken down into three
+distinct problems:
+
+A Finding what nodes to invoke upon. This is the expression found on
+xsl:apply-templates/@select, in the case of template rules
+
+B Concluding what template to invoke. This is the analyzis and evaluation of
+patterns, as found on xsl:template/@match, in the case of templates rules.
+This is seen as a critical, as for instance Michael Kay emphasizes in Saxon:
+Anatomy of an XSLT processor [LINK
+http://www.ibm.com/developerworks/library/x-xslt2/]
+
+C Invoking the template for the given context node
+
+For these three steps, the two first are specific to template rules, while the
+latter, invoking templates, can be seen to be treated identically regardless
+of kind: template rules as well as named templates.
+
+With this perspective as background, lets try to write it into XQuery
+primitives.
+
+First, all templates regardless of kind are instanciated by name. In the case
+of templates rules, a synthetic name is given. They are invoked by an XPath
+function named call-template() that as first argument takes the name of the
+template, and also handles template parameters. This "template callsite"
+which is separated from what it is invoked with and whether it is invoked,
+knows its target template statically, and hence can be subject to inlining,
+and usual functional analysis.
+
+Focus and concatenation of output handled.
+One should consider whether templates couldn't be considered as functions,
+with specialized arguments in the case of tunnel parameters.
+Knowing what templates will be invoked could be used to conclude
+node sorting is not necessary.
+Mention how we do builtin templates
+
+Attribute Value Templates
+-------------------------
+XSL-T make extensive use of Attribute Value Templates(AVTs), which are handled
+by turning the grammar piece in XQuery that is closest, into an expression.
+Simply, ExprSingle[32] is extended with the branch:
+
+AVT LPAREN AttrValueContent RPAREN
+
+where AVT is a synthetic token XSLTokenizer generates. This means that the
+code handling AVTs in XQuery's direct attribute constructors handles AVTs as
+generic expressions. AttrValueContent creates a call to the concat()
+function, over the operands.
+
+Deal with fn:current by using let $current := . return instruction.
+
+Another thing related to order and parsing is that XSL-T has more freedom wrt.
+to where variables are in scope. For instance, a variable declaration appearing
+after a user function declaration is in scope for the function in XSL-T, but
+that's not the case in XQuery. This means that delayed variable resolution must
+be added, something which wasn't, and cannot be active, for the XQuery code.
+See 9.7 Scope of Variables.
+
+The parser generates for the builtin template rules:
+
+    declare template matches (text() | @*) mode #all
+    {
+        text{.}
+    };
+
+    *
+By having templates invocations essentially expressed as a callsite, or
+branching, allows control flow analysis in a traditional manner, and hence the
+possiblity to conclude what templates that are possibly invoked in various
+contexts (or not invoked). One good example where this could improve template
+matching is patterns containg predicates: let's say a template matches text
+nodes with a predicate, but , doh I'm wrong.
+
+The problem with expressing template invocation with if expressions, is finding
+ambiguous matches.
+
+Although normalizing down to a small set of primitives has its advantages, one
+problem is with doing it too early. When doing it directly when tokenization,
+the higher-level perspective is lost and therefore must be restored
+again(example?). For instance, if an error is reported in a primitive, it must
+not appear as originating from that primitive. It's not contstrained to error
+reporting(example?). However, this is a general problem when compilers shift
+between different representations.
+
+One effect this parsing approach has, is that the stylesheet cannot be used as
+an input document(e.g, what document("") would evaluate to); in that case it
+has to be parsed again. I think this is for the better; in the case that the
+stylsheet has this dual role, it means representations are used which are
+designed specifically for these respective roles. Although doing a dual parsing
+step is costly, it's somewhat relieved by that the input is typically cached at
+the byte level(file system and higher layers such as web/application caches) in
+the case of traditional file loading.
+
+Another problem is that the grammar is used to solve implementation details,
+and this might show as part of when the parser do error reporting.
+
+If one decide to not send XSL-T through the XQuery parser, it can be an
+advantage to have as little business logic as possible in the XQuery parser
+such that it can be reused.
+
+Some parts of XSL-T's syntax doesn't translate well to XQUery syntax. Some
+parts doesn't follow structure very strongly, surely not the structures that
+map well to XQuery's syntax. These are xml:base, @version and other attributes
+that can appear on any element. Their information needs to be preserved and
+need to affect the output code, but these cannot be done in a way which fits
+naturally with the XQuery syntax, and hence leads to workarounds. Have whole
+section on how we do @version and @xml:base. Another problem is namespace
+declarations on the top document element.
+
+What largely makes me believe this technique fails is that the large and most
+important parts, templates, instructions, maps well to XQuery, but the small
+but yet not ignorable details like @version and @xml:base does not, to the
+degree that the approach at large fails.
+
+fn:document()
+------------------------
+See class documentation for DocumentFN. Document what optimizations one typically
+wants to implement(const-fold on card 1, constant propagate).
+
+
+In other words, it's reasonable to believe that it's possible to extend the
+XQuery grammar such that it functionality wise is able to do the same as XSL-T,
+but this doesn't equal that it is a good way to reach every gritty corner of
+the XSL-T specification.
+
+Patterns
+--------------------
+The up-side-down turning, discuss id/key().
+
+Declarations
+---------------------
+xsl:function: the 'declare function' declaration. TODO override
+
+XSL-T's error codes goes against good refactoring. Its codes are
+specific on each usage, compared to for instance XPTY0004.
+
+Optimizations: string-join()/value-of
+
+    <xsl:template match="document-node">
+        <xsl:apply-templates select="child::element(doc)"/>
+    </xsl:template>
+
+    <xsl:template match="child-or-top::element(doc)"/>
+
+        =>
+
+    document-node()/child::element(doc) map apply-template
+
+    matches child-or-top::element(doc)
+
+        =>
+
+    N/root(.)//(EE)
+
+    N == document-node()
+    EE == child::element(doc)
+
+        =>
+
+    document-node()/root(.)/descendant-or-self::node()/child::element(doc)
+
+    Optimize out already in createCopyOf()
+
+Bugs:
+    - DynamicContextStore and CurrentItemStore needs to implement
+      evaluateToReceiver().
+    - Don't we have a parsing bug in each place where we call insideSequenceConstructor(), and don't
+      wrap the result in parantheses? E.g, a whitespace node followed by an instruction will lead to parse
+      error if the parent is for instance xsl:when.
+
+In patterns we find:
+    - Function :id()
+    - Function :key()
+    - AxisStep
+    - GenericPredicate. Also used for paths.
+    - (CombineNodes)
+    - empty sequence; attribute::foo()/child::asd
+
+
+Test case, tokenizer asserts(fixed in 2a0e83b):
+        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
+
+
+        <xsl:template match="/">
+        <xsl:call-template name="TestFunction"/>
+        </xsl:template>
+
+
+        <xsl:template name="TestFunction">
+
+
+        <xsl:call-template name="GetElem">
+        <xsl:with-param name="element-set"select="$super/*"/>
+        </xsl:call-template>
+
+        </xsl:template>
+
+        <xsl:template name="GetElem">
+        <xsl:param name="element-set"/>
+        <xsl:copy-of select="$element-set[@name]"/>
+        </xsl:template>
+
+        </xsl:stylesheet>
+
+Typing code:
+
+    <xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">
+
+            <xsl:call-template name="templateName">
+                <xsl:with-param name="a" select="2" />
+            </xsl:call-template>
+
+        </xsl:template>
+
+        <xsl:template name="templateName">
+                <xsl:param name="a" as="xs:integer"/>
+                <xsl:sequence select="$a"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Compat mode in attribute sets:
+    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+        <xsl:attribute-set name="attrSet" version="1.0">
+            <xsl:attribute name="attributeName" select="1 + 'type error without compat mode'"/>
+        </xsl:attribute-set>
+
+        <xsl:template match="/">
+            <out xsl:use-attribute-sets="attrSet"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Space in mode:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">
+                <xsl:apply-templates mode="         #default"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+Type error in global template:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:variable name="wa" as="item()"/><!-- HERE, incorrect cardinality. -->
+
+        <xsl:template name="templateName"/>
+
+    </xsl:stylesheet>
+
+
+Variables are not in scope before its siblings:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template name="templateName">
+            <xsl:sequence select="$var"/>
+            <xsl:variable name="var" select="1"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Crashes:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                    xmlns:local="http://example.com/"
+                    version="2.0">
+
+        <xsl:variable name="var" as="xs:boolean">
+            <xsl:value-of select="local:doesNotExist()"/>
+        </xsl:variable>
+
+    </xsl:stylesheet>
+
+
+
+Whitespace handling, the important part is WS after xsl:template:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/" xml:space="preserve"><MATCH/></xsl:template>
+
+    </xsl:stylesheet>
+
+
+
+Whitespace handling, preserve, but not inside xsl:apply-templates:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w2.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/" xml:space="preserve">MATCH<xsl:apply-templates>
+
+            </xsl:apply-templates></xsl:template>
+
+    </xsl:stylesheet>
+
+Have top-level xml:space, ensure whitespace as child of xsl:stylesheet is ignored:
+
+    <xsl:stylesheet xml:space="preserve" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">MATCH<xsl:apply-templates>
+
+            </xsl:apply-templates>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Compat mode, Saxon & QtXmlPatterns fails:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">
+            <xsl:sequence version="1.0" select="string-join(current-dateTime(), 'separator')"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Compat mode, this is not in the suite:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">
+            <xsl:sequence version="1.0" select="subsequence((1, 2), '2')"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Crashes:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="doc"/>
+
+        <xsl:apply-templates select="item" mode="crazy" />
+
+
+    </xsl:stylesheet>
+
+Incorrectly yields compile error, XPST0003:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match=""/>
+
+        <xsl:apply-templates select="item" mode="crazy" />
+
+    </xsl:stylesheet>
+
+Have a basic simplified stylesheet module:
+
+    <output xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+        <xsl:value-of select="/"/>
+    </output>
+
+Have no @version:
+    <output xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+        <xsl:value-of select="/"/>
+    </output>
+
+
+Is valid:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >
+
+        <xsl:template match="/">
+            <xsl:perform-sort select=".">
+                <xsl:sort select="*"/>
+                <xsl:variable name="abc" select="b"/>
+            </xsl:perform-sort>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+Is valid:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >
+
+        <xsl:template match="/">
+            <xsl:perform-sort select=".">
+                <xsl:sort select="*"/>
+                TEXT
+            </xsl:perform-sort>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+XTSE0020:
+    <literalResultElement xsl:validation="disallowedValue"/>
+
+XTSE0020:
+    <xsl:element name="localName" validation="disallowedValue"/>
+
+XTSE0805:
+    <e xsl:disallowedAttribute=""/>
+
+not XPST0003, not in test suite:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+        <xsl:template match="/">
+            <xsl:variable name="s" as="element()*"/>
+        </xsl:template>
+    </xsl:stylesheet>
+
+Parsing of many exprs in xsl:value-of(with separator):
+
+    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+        <xsl:template match="/">
+            <xsl:value-of separator="SEP">
+                <xsl:sequence select="1"/>
+                <xsl:sequence select="2"/>
+            </xsl:value-of>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+Parsing of many exprs in xsl:value-of(without separator):
+
+    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+        <xsl:template match="/">
+            <xsl:value-of>
+                <xsl:sequence select="1"/>
+                <xsl:sequence select="2"/>
+            </xsl:value-of>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+Check type of empty variables:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+        xmlns:xs="http://www.w3.org/2001/XMLSchema"
+        version="2.0">
+
+        <xsl:template match="/">
+            <xsl:variable name="empty"/>
+
+            <xsl:sequence select="'instance of xs:string:', $empty instance of xs:string, '(should be true)',
+                                  'instance of document-node():', $empty instance of document-node(), '(should be false)',
+                                  'value is:', $empty,
+                                  'END'"/>
+
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+Crashes:
+    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+        <xsl:template match="/">
+            <e xmlns="ABC"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+invalid standard attributes on a simplified stylesheet module.
+
+
+
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+        xmlns:xs="http://www.w3.org/2001/XMLSchema"
+        version="2.0">
+
+        <!-- Type error: applying templates to a variable of type string -->
+        <?spec xslt#applying-templates?>
+        <?error XTTE0520?>
+
+        <xsl:template match="/">
+            <xsl:variable name="empty"/>
+
+            <xsl:sequence select="'instance of xs:string:', $empty instance of xs:string, 'instance of document-node():', $empty instance of document-node()"/>
+
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+        <xsl:template match="/">
+            <output>
+                    <xsl:sequence select="string-length(doesNotMatch)"/>
+                </output>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Asserts(not wellformed):
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+        <xsl:template match="/">
+            <output>
+            </outpu>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+From within a function, use the focus /through/ a variable reference:
+
+    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:local="http://www.w3.org/2005/xquery-local-functions">
+
+        <xsl:variable name="var" select="node()"/>
+
+        <xsl:function name="local:function">
+            <xsl:sequence select="$var"/>
+        </xsl:function>
+
+        <xsl:template match="/">
+            <xsl:sequence select="local:function()"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+
+
+Loops infinitely:
+
+        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+
+            <xsl:template match="/" version="1.0">
+                <xsl:namespace name="{doc/item}" select="'http://www.example.com'" version="1.0"/>
+            </xsl:template>
+
+        </xsl:stylesheet>
+
+
+Gives crash in coloring code:
+    Stylesheet:
+        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+            <xsl:template match="/">
+            </xsl:template>
+
+        </xsl:stylesheet>
+
+    Focus:
+        <a><b/><</a>
+
+
+Should evaluate to true:
+
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
+
+        <xsl:template match="/">
+            <xsl:call-template name="yo">
+                <xsl:with-param name="arg" as="xs:integer">
+                    <xsl:sequence select="xs:untypedAtomic('1')"/>
+                </xsl:with-param>
+            </xsl:call-template>
+        </xsl:template>
+
+        <xsl:template name="yo">
+            <xsl:param name="arg"/>
+            <xsl:sequence select="$arg instance of xs:integer"/>
+        </xsl:template>
+
+    </xsl:stylesheet>
+
+Crashes, should be XTTE0570:
+    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                    exclude-result-prefixes="xs" version="2.0">
+
+    <xsl:template match="/">
+        <xsl:apply-templates>
+            <xsl:with-param name="second_seq" as="xs:string">
+            </xsl:with-param>
+
+        </xsl:apply-templates>
+    </xsl:template>
+
+    <xsl:template match="empty">
+        <xsl:param name="second_seq">def</xsl:param>
+        <xsl:sequence select="$second_seq instance of xs:string"/>
+    </xsl:template>
+
+    </xsl:stylesheet>
+
+* Parse error:
+
+        <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+            <xsl:template match="/">
+                <xsl:copy>
+                    <xsl:sequence select="1"/>
+                    <xsl:sequence select="2"/>
+                </xsl:copy>
+            </xsl:template>
+
+        </xsl:stylesheet>
+
+* Write tests with xsl:with-param whose body is empty. That's effectively an
+  empty sequence(?) which needs to be handled properly, and (dynamically) type
+  checked correctly.
+
+--------------------------------------------------------------------------
+
+
+
+
+
+--------------------------------------------------------------------------
+
+
+
+        -------------------------------------------------------------
+        /a/b
+
+         =>
+
+        b[parent::a[parent::document()]]
+
+        but we currently have:
+
+        (b[parent::a])[parent::document()]
+
+        -------------------------------------------------------------
+        a/b
+
+        =>
+
+        b[parent::a]
+
+        -------------------------------------------------------------
+        a/b/c
+
+        =>
+
+        c[parent::b[parent::a]]
+
+        -------------------------------------------------------------
+        a/b/c/d
+
+        =>
+
+        d[parent::c[parent::b[parent::a]]]
+
+
+        -------------------------------------------------------------
+        /a/b/c/d
+
+        =>
+
+        d[parent::c[parent::b[parent::a[parent::document()]]]]
+
+        This is handled specially; see | SLASH RelativePathPattern
+
+
+        b/c rewrites to:
+            TruthPredicate
+                AxisStep    self::element(c)
+                AxisStep    parent::element(b)
+
+        For a/b/c we get:
+
+            TruthPredicate
+                TruthPredicate
+                    AxisStep    self::element(c)
+                    AxisStep    parent::element(b)
+                AxisStep    parent::element(a)
+
+        But we want:
+
+            TruthPredicate
+                AxisStep    child-or-top::element(c)
+                TruthPredicate
+                    AxisStep    parent::element(b)
+                    AxisStep    parent::element(a)
+
+        For a/b/c/d we get:
+
+            TruthPredicate
+                TruthPredicate
+                    TruthPredicate
+                        AxisStep    self::element(d)
+                        AxisStep    parent::element(c)
+                    AxisStep    parent::element(b)
+                AxisStep    parent::element(a)
+
+        For a/b/c/d we want:
+
+            TruthPredicate
+                AxisStep    self::element(d)
+                TruthPredicate
+                    AxisStep    parent::element(c)
+                    TruthPredicate
+                        AxisStep    parent::element(b)
+                        AxisStep    parent::element(a)
+
+
+        For /a/b we get:
+
+            TruthPredicate
+                TruthPredicate:
+                    AxisStep    self::element(b)
+                    AxisStep    parent::element(a)
+                AxisStep    parent::document()
+
+        but we want:
+
+            TruthPredicate
+                AxisStep    self::element(b)
+                TruthPredicate: // PREDICATE
+                    AxisStep    parent::element(a)
+                    AxisStep    parent::document() // PREDICATE
+
+    --------------------------------------------------------------
+    For a/b/c we get:
+        TruthPredicate
+            AxisStep self::element(c)
+            TruthPredicate
+                parent::element(b)
+                parent::element(a)
+