Optimizations and performance improvements
Expressions of the form //x/y are where possible now rewritten as
        descendant::y[parent::x]. This removes the need for sorting into document
      order, and it makes the code streamable. If the selection is not from the document node, for
      example .//x/y, then it is rewritten as
        child::*/descendant::y[parent::x].
Axis steps using node tests that match non-element nodes are now recognized where appropriate
      as peer expressions, where the nodes are non-overlapping and therefore streamable: an example
      is descendant::text(). (Such expressions can arise as the result of the previous
      optimization, for example .//title/text() is translated into
        child::*/descendant::text()[parent::title].)
Where two or more expressions of the form //x[a=b] occur, and both are
      translated to calls on the key() function with a suitable key definition, Saxon
      now checks whether they can make use of the same key definition, which potentially means that
      only one index is constructed instead of multiple identical indexes.