/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QVector>

#include "qabstractxmlnodemodel_p.h"
#include "qabstractxmlreceiver.h"
#include "qcommonvalues_p.h"
#include "qemptyiterator_p.h"
#include "qitemmappingiterator_p.h"
#include "qitem_p.h"
#include "qnamespaceresolver_p.h"
#include "qsequencemappingiterator_p.h"
#include "qsingletoniterator_p.h"

#include "qabstractxmlnodemodel.h"

QT_BEGIN_NAMESPACE

using namespace QPatternist;

typedef QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndexIteratorPointer;

/**
 * @file
 * @short Contains the implementation of QAbstractXmlNodeModel.
 */

bool QAbstractXmlNodeModel::isIgnorableInDeepEqual(const QXmlNodeModelIndex &n)
{
    Q_ASSERT(!n.isNull());
    const QXmlNodeModelIndex::NodeKind nk = n.kind();
    return nk == QXmlNodeModelIndex::ProcessingInstruction ||
           nk == QXmlNodeModelIndex::Comment;
}


/*!
  \class QAbstractXmlNodeModel
  \brief The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML for QXmlQuery.
  \threadsafe
  \since 4.4
  \ingroup xml-tools
  \inmodule QtXmlPatterns

  The QAbstractXmlNodeModel specifies the interface that a node model
  must implement for that node model be accessible to the query engine
  for processing XQuery queries.  A node model represents data as a
  structure that can be queried as if the data were XML.

  The node model represented by a subclass of QAbstractXmlNodeModel is
  meant to be accessed by the Qt XML Patterns query engine. If the API
  seems a little strange in a few places, it is because the member
  functions are called by the query engine as it evaluates an
  XQuery. They aren't meant to be used programatically.

  \section1 Usage

  QAbstractXmlNodeModel bridges the gap between the arbitrary structure
  of the non-XML data to be queried and the well-defined structure of
  XML data understood by QXmlQuery.

  Consider a chemistry application that reads the file \c
  chemistryData, which contains non-XML data that represents a
  chemical structure composed of molecules and atoms. The application
  will query this chemistry data with an XQuery it reads from file \c
  queryFile. We write a custom subclass of QAbstractXmlNodeModel (\c
  ChemistryNodeModel) that reads \c chemistryData and builds a data
  structure, perhaps composed of objects of our own classes \c
  molecule and \c atom.  Clearly, this data structure is not XML. Our
  custom subclass will know how to traverse this non-XML structure and
  present it through the \l
  {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model interface}.

  \snippet code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1

  The application first creates an instance of QXmlQuery and calls \l
  {QXmlQuery::setQuery()}{setQuery()} to read \c queryFile containing
  the XQuery we want to run. Then it creates an instance of our custom
  node model class, \c ChemistryNodeModel, which is a subclass of
  QAbstractXmlNodeModel. Its constructor is called with the \l
  {QXmlNamePool} {name pool} obtained from our QXmlQuery, and with the
  \c chemistryFile containing the structure of molecules and atoms to
  be queried. The \l {QXmlNamePool} {name pool} is required because
  our custom node model has the member function \l
  {QAbstractXmlNodeModel::name()} {name()}, which returns the \l
  {QXmlName} {name} of any node in the model. The \l {QXmlQuery}
  {query} and the custom node model must use the same name pool for
  constructing these \l {QXmlName} {names}. The constructor would then
  read \c chemistryFile and build the custom node model structure.

  To connect the \c query to the custom node model, we must bind a
  variable name used in the query to a node in the model. The variable
  can then be used in the query as a starting node. First, an \l
  {QXmlNodeModelIndex} {index} for the desired starting node is
  retrieved by calling QAbstractXmlNodeModel::createIndex(). Then the
  index is bound to a variable name, in this case \c queryRoot, by
  passing the name and the index to QXmlQuery::bindVariable(). The
  query can then use a variable reference \c $queryRoot to refer to
  the starting node. Note that if the \l {QXmlQuery} {query} uses
  multiple variable references, a call to QXmlQuery::bindVariable()
  is required to bind each different variable name to a node in the
  model.

  The query is executed when the application calls one of the
  QXmlQuery evaluation functions. The application uses
  QXmlQuery::evaluateTo(QAbstractXmlReceiver *), because it then uses
  a \l {QXmlSerializer} {serializer} to out the query result as XML to
  \c stdout. We could have used QXmlQuery::evaluateTo(QXmlResultItems
  *) to get a list of result items, or
  QXmlQuery::evaluateTo(QStringList *) if the query evaluated to a
  sequence of \c {xs:string} values.

  During query execution, the engine iterates over the node model
  using nextFromSimpleAxis() to get the \l {QXmlNodeModelIndex}
  {index} of the next node to be visited. The engine can get the name
  of a node by calling name() with the node's \l {QXmlNodeModelIndex}
  {index}. stringValue(), baseUri(), documentUri() and kind() are also
  called as needed with a node \l {QXmlNodeModelIndex} {index}.

  The example demonstrates the standard pattern for using a subclass
  of QAbstractXmlNodeModel in combination with QXmlQuery to perform
  an XQuery.

  \list 1

    \li Instantiate QXmlQuery and give it the XQuery to be run;

    \li Instantiate a subclass of QAbstractXmlNodeModel or
    QSimpleXmlNodeModel;

    \li Retrieve a QXmlNodeModelIndex for the node in the model where
    the QXmlQuery should start the query;

    \li Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex
    to \c {$variable name};

    \li Call one of the QXmlQuery evaluation functions to run the
    query.

  \endlist

  \section1 Subclassing

  Because the \l {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model
  interface} presented by QAbstractXmlNodeModel allows QXmlQuery to
  operate on non-XML data as if it were XML, implementing subclasses
  of QAbstractXmlNodeModel can involve a significant amount of
  work. The QSimpleXmlNodeModel class is provided to simplify the
  implementation for many common use cases.

  \section1 Thread Safety

  Because the node model can be accessed concurrently by threads in
  the Qt XML Patterns module, subclasses of QAbstractXmlNodeModel must
  be written to be \l{Reentrancy and Thread-Safety}{thread-safe}.
  Classes that simplify implementing thread-safety include QReadLocker
  and QWriteLocker.

  See the example \l{File System Example} for a demonstration.
 */

/*!
  \enum QXmlNodeModelIndex::Constants

  \value ForwardAxis All forward axes include this flag.
  \value ReverseAxis All reverse axes include this flag.
 */

/*!
  \enum QXmlNodeModelIndex::DocumentOrder

  Identifies the specific node comparison operator that should be
  used.

  \value Precedes Signifies the \c \<\< operator. Test whether the
         first operand precedes the second in the document.

  \value Follows Signifies the \c \>\> operator. Test whether the
                 first operand follows the second in the document.

  \value Is Signifies the \c is operator. Test whether two nodes have
  the same node identity.
 */

/*!
  \enum QAbstractXmlNodeModel::SimpleAxis

  Four axes that each contain one node only.

  \value Parent The parent of the context node
  \value FirstChild The first child of the context node
  \value PreviousSibling The previous child of the context node
  \value NextSibling The next child of the context node
*/

/*!
 \enum QXmlNodeModelIndex::Axis
 \internal

   Identify the axes emanating from a node.

   The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf,
   AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are
   forward axes.

   The axes AxisParent, AxisAncestor, AxisPrecedingSibling,
   AxisPreceding and AxisAncestorOrSelf are reverse axes.

   \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}

   \value AxisChild                The \c child axis.

   \value AxisDescendant           The \c descendant axis.

   \value AxisAttribute            The \c attribute axis. Note: There
                                   is a node kind named \c{Attribute}.

   \value AxisSelf                 The \c self axis.

   \value AxisDescendantOrSelf     The \c descendant-or-self axis.

   \value AxisFollowingSibling     The \c following-sibling axis.

   \value AxisNamespace            The \c namespace axis. Note: Does
                                   not exist in XQuery; deprecated in
                                   XPath 2.0 (optionally supported);
                                   mandatory in XPath 1.0.

   \value AxisFollowing            The \c following axis.

   \value AxisParent               The \c parent axis.

   \value AxisAncestor             The \c ancestor axis.

   \value AxisPrecedingSibling     The \c preceding-sibling axis.

   \value AxisPreceding            The \c preceding axis.

   \value AxisAncestorOrSelf       The \c ancestor-or-self axis.
*/

using namespace QPatternist;

/*!
  Default constructor.
 */
QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0)
{
}

/*!
 \internal

 Takes the d-pointer.

 */
QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d)
{
}

/*!
  Destructor.
 */
QAbstractXmlNodeModel::~QAbstractXmlNodeModel()
{
}

/*!
  \typedef QAbstractXmlNodeModel::List

  A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart
  pointers} to instances of QAbstractXmlNodeModel.

  \sa QExplicitlySharedDataPointer
 */

/*!
  \typedef QAbstractXmlNodeModel::Ptr

  A \l {QExplicitlySharedDataPointer} {smart pointer} to an
  instance of QAbstractXmlNodeModel.

  \sa QExplicitlySharedDataPointer
 */

/*!
  \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const

  Returns the base URI for the node whose index is \a n. The caller
  guarantees that \a n is not \c null and that it belongs to a node
  in this node model.

  The base URI of a node can be extracted using the \c fn:base-uri()
  function. The base URI is typically used for resolving relative URIs
  that appear in the node or its children. It is conformant to just
  return the document URI, although that might not properly reflect
  the underlying data.

  This function maps to the \c dm:base-uri accessor, which returns
  a base URI according to the following:

  \list

  \li For document nodes, the base URI and the document URI are the same.

  \li For elements, the base URI is the URI appearing in the element's
     \c xml:base attribute, if present, or it is resolved to the
     parent element's base URI.

  \li Namespace nodes have no base URI.

  \li The base URI for a processing instruction, comment, attribute,
  or text node is the base URI of the node's parent element.

  \endlist

  The implementation guarantees to return a valid QUrl, or a default
  constructed QUrl. If a node has no base URI, as in the case where a
  comment has no parent, a default constructed QUrl is returned.

   \sa {http://www.w3.org/TR/xpath-datamodel/#dm-base-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.2 base-uri Accessor}
 */

/*!
  \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const

  Returns the document URI of \a n. The document URI identifies the
  resource which is the document. For example, the document could be a
  regular file, e.g., \c{file:/}, or it could be the \c{http://} URL of
  the location of a file. The document URI is used for resolving URIs
  and to simply know where the document is.

  If the node model maps to a URI in a natural way, return that URI.
  Otherwise, return the company or product URI. The document URI can
  be any URI as long as its valid and absolute.

  The caller guarantees that \a n is not \c null and that it belongs
  to this QAbstractXmlNodeModel.

  This function maps to the \c dm:document-uri accessor, which
  returns a document URI according to the following:

  \list

  \li If \a n is a document node, return an absolute QUrl containing
     the document URI, or a default constructed QUrl. The latter
     signals that no document URI is available for the document node.

  \li For all other nodes, return a default constructed QUrl.

  \endlist

  \sa {http://www.w3.org/TR/xpath-datamodel/#dm-document-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.4 document-uri Accessor}
  \sa QUrl::isValid(), QUrl::isRelative()
 */

/*
### Qt 5:

Add the function:

    virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;

Such that the data model can communicate back source locations.
 */

/*!
  \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const

  Returns a value indicating the kind of node identified by \a ni.
  The caller guarantees that \a ni is not null and that it identifies
  a node in this node model. This function maps to the \c
  dm:node-kind() accessor.

  \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-kind}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.10 node-kind Accessor}
 */

/*!
  \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const

  This function returns the relative document order for the
  nodes indexed by \a ni1 and \a ni2. It is used for the \c Is
  operator and for sorting nodes in document order.

  The caller guarantees that \a ni1 and \a ni2 are not \c null and
  that both identify nodes in this node model.

  If \a ni1 is identical to \a ni2, QXmlNodeModelIndex::Is is returned.
  If \a ni1 precedes \a ni2 in document order, QXmlNodeModelIndex::Precedes
  is returned. If \a ni1 follows \a ni2 in document order,
  QXmlNodeModelIndex::Follows is returned.

  \sa {http://www.w3.org/TR/xpath-datamodel/#document-order}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 2.4 Document Order}
 */

/*!
  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const

  Returns the root node of the tree that contains the node whose index
  is \a n. The caller guarantees that \a n is not \c null and that it
  identifies a node in this node model.

  If \a n identifies a node that is a direct child of the root,
  parent() would return the same QXmlNodeModelIndex returned by
  this function.
 */

namespace QPatternist
{
    class MergeIterator
    {
    public:

        inline
        QXmlNodeModelIndexIteratorPointer
        mapToSequence(const QXmlNodeModelIndexIteratorPointer &it,
                      const DynamicContext::Ptr &) const
        {
            return it;
        }
    };

    static const MergeIterator mergeIterator = {};

    /**
     * One might wonder, why not use makeVectorIterator() directly on a QVector
     * with iterators?
     *
     * A problem emerges QAbstractXmlForwardIterator::copy(). All "meta
     * iterators" that contain other iterators and so forth, propagate the
     * copy() call such that all involved iterators are copied. However, if we
     * have a ListIterator of iterators it isn't aware of that it contains
     * iterators. Hence, we have this class which is specialized(not in the
     * template sense) on iterators, and hence copies them appropriately.
     */
    class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
    {
        typedef QVector<QXmlNodeModelIndexIteratorPointer> ItVector;
    public:
        typedef QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr Ptr;

        IteratorVector(const ItVector &in) : ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >(in)
        {
        }

        QAbstractXmlForwardIterator<QXmlNodeModelIndexIteratorPointer>::Ptr copy() const override
        {
            ItVector result;
            const int count = m_list.count();
            result.reserve(count);
            for (int i = 0; i < count; ++i)
                result.append(m_list.at(i)->copy());

            return Ptr(new IteratorVector(result));
        }
    };
}

/*!
 \internal
 This function is not a private member of QAbstractXmlNodeModel
 because it would be messy to forward declare the required types.
*/
static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node,
                                                               const QXmlNodeModelIndexIteratorPointer &it2)
{
    QVector<QXmlNodeModelIndexIteratorPointer> iterators;
    iterators.reserve(2);
    iterators.append(makeSingletonIterator(node));
    iterators.append(it2);

    return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
                                                           IteratorVector::Ptr(new IteratorVector(iterators)),
                                                           DynamicContext::Ptr());
}

inline QAbstractXmlForwardIterator<QXmlNodeModelIndex>::Ptr
QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni,
                                     const DynamicContext::Ptr &) const
{
    Q_ASSERT(!ni.isNull());
    /* Since we pass in this here, mapToSequence is used recursively. */
    return mergeIterators(ni, makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
                                                                              ni.iterate(QXmlNodeModelIndex::AxisChild),
                                                                              DynamicContext::Ptr()));
}

/*!
  \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const

  Returns the attributes of \a element. The caller guarantees
  that \a element is an element in this node model.
 */

/*!
  \internal

  Performs navigation, starting from \a ni, by returning an
  QAbstractXmlForwardIterator that returns nodes the \a axis emanating
  from \a ni.

  The implementation returns the nodes on the \a axis, without
  duplicates and in \a axis order. This means that if \a axis is a
  reverse axis, which is the case for the \c parent, \c ancestor, \c
  ancestor-or-self, \c preceding, and \c preceding-sibling, the nodes
  are delivered in reverse document order. Otherwise the nodes are
  delivered in document order.

  The implementor guarantees that the nodes delivered for the axes are
  consistent with the XPath Data Model. This just implies common
  sense, e.g., The child axis for a comment node can't contain any
  children; a document node can't be a child of an element, etc.
  Attributes aren't considered children of an element, but are only
  available on AxisAttribute.

  The value past in \a axis is not guaranteed based on what is used in
  a query. Qt XML Patterns may call this function arbitrarily with any
  value for \a axis. This is because Qt XML Patterns may rewrite queries
  to be more efficient, using axes in different ways from the original
  query.

  QAbstractXmlNodeModel::Axis has a good overview of the axes and what
  they select.

  The caller guarantees that \a ni is not \c null and that it belongs
  to this QAbstractXmlNodeModel instance.

  Implementing iterate() can involve significant work, since it
  requires different iterators for all the axes used. In the worst
  case, it could require writing as many QAbstractXmlForwardIterator
  subclasses as there are axes, but the number can often be reduced
  with clever use of lists and template classes. It is better to use
  or subclass QSimpleXmlNodeModel, which makes it easier to write the
  node navigation code without loss of efficiency or flexibility.

  \sa QSimpleXmlNodeModel
  \sa QXmlNodeModelIndex::Axis
  \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes}
  \sa {http://www.w3.org/TR/xpath-datamodel/}{W3CXQuery 1.0 and XPath 2.0 Data Model (XDM)}
 */
QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> >
QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni,
                               QXmlNodeModelIndex::Axis axis) const
{
    /* Returns iterators that track state and calls nextFromSimpleAxis()
     * iteratively. Typically, when sub-classing QSimpleXmlNodeModel,
     * you don't reimplement this function, but instead implement
     * nextFromSimpleAxis(). */

    switch(axis)
    {
        case QXmlNodeModelIndex::AxisSelf:
            return makeSingletonIterator(ni);
        case QXmlNodeModelIndex::AxisParent:
        {
            if(kind(ni) == QXmlNodeModelIndex::Document)
                return makeEmptyIterator<QXmlNodeModelIndex>();
            else
                return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
        }
        case QXmlNodeModelIndex::AxisNamespace:
            return makeEmptyIterator<QXmlNodeModelIndex>();
        case QXmlNodeModelIndex::AxisAncestor:
        {
            QList<QXmlNodeModelIndex> ancestors;
            QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);

            while(!ancestor.isNull())
            {
                ancestors.append(ancestor);
                ancestor = nextFromSimpleAxis(Parent, ancestor);
            }

            return makeListIterator(ancestors);
        }
        case QXmlNodeModelIndex::AxisAncestorOrSelf:
        {
            QList<QXmlNodeModelIndex> ancestors;
            ancestors.append(ni);
            QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni);

            while(!ancestor.isNull())
            {
                ancestors.append(ancestor);
                ancestor = nextFromSimpleAxis(Parent, ancestor);
            }

            return makeListIterator(ancestors);
        }
        case QXmlNodeModelIndex::AxisPrecedingSibling:
        {
            QList<QXmlNodeModelIndex> preceding;
            QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni);

            while(!sibling.isNull())
            {
                preceding.append(sibling);
                sibling = nextFromSimpleAxis(PreviousSibling, sibling);
            }

            return makeListIterator(preceding);
        }
        case QXmlNodeModelIndex::AxisFollowingSibling:
        {
            QList<QXmlNodeModelIndex> preceding;
            QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni);

            while(!sibling.isNull())
            {
                preceding.append(sibling);
                sibling = nextFromSimpleAxis(NextSibling, sibling);
            }

            return makeListIterator(preceding);
        }
        case QXmlNodeModelIndex::AxisChildOrTop:
        {
            if(nextFromSimpleAxis(Parent, ni).isNull())
            {
                switch(kind(ni))
                {
                    case QXmlNodeModelIndex::Comment:
                    case QXmlNodeModelIndex::ProcessingInstruction:
                    case QXmlNodeModelIndex::Element:
                    case QXmlNodeModelIndex::Text:
                        return makeSingletonIterator(ni);
                    case QXmlNodeModelIndex::Attribute:
                    case QXmlNodeModelIndex::Document:
                    case QXmlNodeModelIndex::Namespace:
                        /* Do nothing. */;
                }
            }

            Q_FALLTHROUGH();
        }
        case QXmlNodeModelIndex::AxisChild:
        {
            QList<QXmlNodeModelIndex> children;
            QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni);

            while(!child.isNull())
            {
                children.append(child);
                child = nextFromSimpleAxis(NextSibling, child);
            }

            return makeListIterator(children);
        }
        case QXmlNodeModelIndex::AxisDescendant:
        {
            return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
                                                                   ni.iterate(QXmlNodeModelIndex::AxisChild),
                                                                   DynamicContext::Ptr());
        }
        case QXmlNodeModelIndex::AxisAttributeOrTop:
        {
            if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull())
                return makeSingletonIterator(ni);

            Q_FALLTHROUGH();
        }
        case QXmlNodeModelIndex::AxisAttribute:
            return makeVectorIterator(attributes(ni));
        case QXmlNodeModelIndex::AxisDescendantOrSelf:
            return mergeIterators(ni, iterate(ni, QXmlNodeModelIndex::AxisDescendant));
        case QXmlNodeModelIndex::AxisFollowing:
        case QXmlNodeModelIndex::AxisPreceding:
        {
            /* We walk up along the ancestors, and for each parent, we grab its preceding/following
             * siblings, and evaluate the descendant axis. The descendant axes gets added
             * to a list and we then merge those iterators. */
            QVector<QXmlNodeModelIndexIteratorPointer> descendantIterators;

            QXmlNodeModelIndex current(ni);
            while(!current.isNull())
            {
                QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current));
                if(candidate.isNull())
                {
                    /* current is an ancestor. We don't want it, so next iteration we
                     * will grab its preceding sibling. */
                    current = nextFromSimpleAxis(Parent, current);
                }
                else
                {
                    current = candidate;
                    descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
                }
            }

            return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
                                                                   IteratorVector::Ptr(new IteratorVector(descendantIterators)),
                                                                   DynamicContext::Ptr());
        }
    }

    Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
    return makeEmptyIterator<QXmlNodeModelIndex>();
}

/*!
  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const

  When Qt XML Patterns evaluate path expressions, it emulate them through a
  combination of calls with QSimpleXmlNodeModel::SimpleAxis values. Therefore,
  the implementation of this function must return the node, if any, that
  appears on the \a axis emanating from the \a origin.

  If no such node is available, a default constructed
  QXmlNodeModelIndex is returned.

  QSimpleXmlNodeModel eliminates the need to handle redundant corner
  cases by guaranteeing that it will never ask for:

  \list
    \li Children or siblings for attributes.
    \li Children for comments, processing instructions, and text nodes.
    \li Siblings or parents for document nodes.
  \endlist

  A typical implementation performs a \c switch on the value of \a
  axis:

  \code
  QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const
  {
    // Convert the QXmlNodeModelIndex to a value that is specific to what we represent.
    const MyValue value = toMyValue(ni);

    switch(axis)
    {
        case Parent:
            return toNodeIndex(value.parent());
        case FirstChild:
        case PreviousSibling:
        case NextSibling:
            // and so on
    }
  }
  \endcode

 */

/*!
  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const

  Creates a node index with \a data as its internal data. \a data is
  not constrained.
 */

/*!
  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const

  Creates a node index with \a pointer and \a additionalData as
  its internal data.

  What \a pointer and \a additionalData is, is not constrained.
 */

/*!
  \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const;
  \overload

  Creates a QXmlNodeModelIndex containing \a data and \a
  additionalData.
 */

/*!
  \fn  QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const

  Returns the name of \a ni. The caller guarantees that \a ni is not
  \c null and that it belongs to this QAbstractXmlNodeModel.

  If a node does not have a name, e.g., comment nodes, a null QXmlName
  is returned. QXmlNames must be created with the instance of
  QXmlQuery that is being used for evaluating queries using this
  QAbstractXmlNodeModel.

  This function maps to the \c dm:node-name() accessor.

  If \a ni is a processing instruction, a QXmlName is returned with
  the local name as the target name and the namespace URI and prefix
  both empty.

  \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-name}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.11 node-name Accessor}
  \sa QXmlName
 */

/*!
  \fn QVector<QXmlName> QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const

  Returns the in-scope namespaces of \a n. The caller guarantees that
  \a n is not \c null and that it belongs to this QAbstractXmlNodeModel.

  This function corresponds to the \c dm:namespace-nodes accessor.

  The returned vector of namespace declarations includes namespaces
  of the ancestors of \a n.

  The caller guarantees that \a n is an Element that belongs to this
  QAbstractXmlNodeModel.
 */

/*!
  \internal
  Sends the namespaces declared on \a n to \a receiver.

  As a consequence, no namespaces are sent unless this node is an
  element and has namespaces declared.

  The caller guarantees that \a n is not \c null and that it belongs
  to this QAbstractXmlNodeModel instance.

  Note that it is not the namespaces that are in scope on \a n, but
  only the namespaces that are specifically declared on \a n.

  \a receiver is the receiver that this node is supposed to send its
  namespaces to. This is guaranteed by the caller to be a valid
  pointer.  \a n is the index of the node whose namespaces are to
  be sent.
 */
void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n,
                                           QAbstractXmlReceiver *const receiver) const
{
    Q_ASSERT(receiver);
    const QVector<QXmlName> nss(namespaceBindings(n));

    /* This is by far the most common case. */
    if(nss.isEmpty())
        return;

    const int len = nss.size();
    for(int i = 0; i < len; ++i)
        receiver->namespaceBinding(nss.at(i));
}

/*!
  \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const

  Returns the string value for node \a n.

  The caller guarantees that \a n is not \c null and that it belong to
  this QAbstractXmlNodeModel instance.

  This function maps to the \c dm:string-value() accessor, which the
  specification completely specifies. Here's a summary:

  \list

  \li For processing instructions, the string value is the data
  section(excluding any whitespace appearing between the name and the
  data).

  \li For text nodes, the string value equals the text node.

  \li For comments, the content of the comment

  \li For elements, the concatenation of all text nodes that are
  descendants. Note, this is not only the children, but the
  childrens' childrens' text nodes, and so forth.

  \li For document nodes, the concatenation of all text nodes in the
  document.

  \endlist

  \sa {http://www.w3.org/TR/xpath-datamodel/#dm-string-value}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.13 string-value Accessor}
 */

/*!
  \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const

  Returns the typed value for node \a node.

  The typed value is an atomic value, which an element or attribute
  contains.

  The caller guarantees that \a node is either an element or an
  attribute. The implementor guarantees that the returned QVariant has
  a value which is supported in XQuery. It cannot be an arbitrary
  QVariant value.  The implementor also guarantees that stringValue()
  returns a lexical representation of typedValue() (this is guaranteed
  by QSimpleXmlNodeModel::stringValue()).

  If the return QVariant is a default constructed variant, it signals
  that \a node has no typed value.
*/

/*!
   \internal
 */
QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const
{
    const QVariant &candidate = typedValue(ni);
    if(candidate.isNull())
        return QPatternist::CommonValues::emptyIterator;
    else
        return makeSingletonIterator(AtomicValue::toXDM(candidate));
}

/*!
 \internal
 */
QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const
{
    Q_ASSERT_X(false, Q_FUNC_INFO,
               "This function is internal and must not be called.");
    return QPatternist::ItemTypePtr();
}

/*!
  \internal

  Returns the namespace URI on \a ni that corresponds to \a prefix.

  If \a prefix is StandardPrefixes::empty, the namespace URI for the
  default namespace is returned.

  The default implementation use namespaceBindings(), in a straight
  forward manner.

  If no namespace exists for \a prefix, NamespaceResolver::NoBinding
  is returned.

  The caller guarantees to only call this function for element nodes.
 */
QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni,
                                                                  const QXmlName::PrefixCode prefix) const
{
    Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element);

    const QVector<QXmlName> nbs(namespaceBindings(ni));
    const int len = nbs.size();

    for(int i = 0; i < len; ++i)
    {
        if(nbs.at(i).prefix() == prefix)
            return nbs.at(i).namespaceURI();
    }

    return NamespaceResolver::NoBinding;
}


/*!
  \internal

  Determines whether \a ni1 is deep equal to \a ni2.

  isDeepEqual() is defined as evaluating the expression \c
  fn:deep-equal($n1, $n2) where \c $n1 is \a ni1 and \c $n1 is \a
  ni2. This function is associative, meaning the same value is
  returned regardless of if isDeepEqual() is invoked with \a ni1 as
  first argument or second. It is guaranteed that \a ni1 and \a ni2
  are nodes, as opposed to the definition of \c fn:deep-equal().

  Returns true if \a ni1 is deep-equal to \a ni2, otherwise false

  \sa {"http://www.w3.org/TR/xpath-functions/#func-deep-equal"}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.3.1 fn:deep-equal}
 */
bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1,
                                        const QXmlNodeModelIndex &n2) const
{
    Q_ASSERT(!n1.isNull());
    Q_ASSERT(!n2.isNull());

    const QXmlNodeModelIndex::NodeKind nk = n1.kind();

    if(nk != n2.kind())
        return false;

    if(n1.name() != n2.name())
        return false;

    switch(nk)
    {
        case QXmlNodeModelIndex::Element:
        {
            QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute));
            QXmlNodeModelIndex node(atts1->next());

            const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList());
            const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());

            while(!node.isNull())
            {
                bool equal = false;
                for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
                {
                    if(isDeepEqual(node, (*it)))
                        equal = true;
                }

                if(!equal)
                    return false;

                node = atts1->next();
            }

            /* Fallthrough, so we check the children. */
            Q_FALLTHROUGH();
        }
        case QXmlNodeModelIndex::Document:
        {
            QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild));
            QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild));

            while(true)
            {
                QXmlNodeModelIndex no1(itn1->next());
                QXmlNodeModelIndex no2(itn2->next());

                while(!no1.isNull() && isIgnorableInDeepEqual(no1))
                    no1 = itn1->next();

                while(!no2.isNull() && isIgnorableInDeepEqual(no2))
                    no2 = itn2->next();

                if(!no1.isNull() && !no2.isNull())
                {
                   if(!isDeepEqual(no1, no2))
                       return false;
                }
                else
                    return no1.isNull() && no2.isNull();
            }

            return true;
        }
        case QXmlNodeModelIndex::Attribute:
        case QXmlNodeModelIndex::ProcessingInstruction:
        case QXmlNodeModelIndex::Text:
        case QXmlNodeModelIndex::Comment:
            return n1.stringValue() == n2.stringValue();
        case QXmlNodeModelIndex::Namespace:
        {
            Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
            return false;
        }
    }

    return false;
}

/*!
  \class QXmlItem
  \reentrant
  \since 4.4
  \brief The QXmlItem class contains either an XML node or an atomic value.
  \ingroup xml-tools
  \inmodule QtXmlPatterns

  In XQuery, all expressions evaluate to a sequence of items, where
  each item is either an XML node or an atomic value. The query in the
  following snippet evaluates to sequence of five items.

  \quotefile patternist/items.xq

  The five items are: An element, an atomic value (binary data encoded
  in base64), a date, a float, and an attribute.

  QXmlItem is the class that represents these XQuery items in the
  Qt XML Patterns API. A non-null instance of QXmlItem is either a node
  or an atomic value. Calling isNode() or isAtomicValue() tells you
  which it is. Atomic values are represented elsewhere in the Qt API
  as instances of QVariant, and an instance of QXmlItem that
  represents an atomic value can be converted to a QVariant by calling
  toAtomicValue(). A QXmlItem that wraps a node is represented
  elsewhere as an instance of QXmlNodeModelIndex. A node QXmlItem can
  be converted to a QXmlNodeModelIndex by calling toNodeModelIndex().

  A default constructed QXmlItem instance is neither a node nor an
  atomic value. It is considered null, in which case isNull() returns
  true.

  An instance of QXmlItem will be left dangling if the
  \l{QAbstractXmlNodeModel} {XML node model} it
  refers to is deleted, if it is a QXmlNodeModelIndex.
 */

/*!
  \typedef QXmlItem::Iterator
  A QAbstractXmlForwardIterator over QXmlItem.
 */

/*!
  Constructs a null QXmlItem that is neither a node nor an atomic
  value. isNull() returns true for a default constructed instance.
 */
QXmlItem::QXmlItem()
{
    m_node.reset();
}

bool QXmlItem::internalIsAtomicValue() const
{
    return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
}

/*!
  The copy constructor constructs a copy of \a other.
 */
QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
{
    if(internalIsAtomicValue())
        m_atomicValue->ref.ref();
}

/*!
  Constructs an atomic value QXmlItem with \a atomicValue.

  \sa isAtomicValue()
 */
QXmlItem::QXmlItem(const QVariant &atomicValue)
{
    m_node.reset();
    if(atomicValue.isNull())
    {
        /* Then we behave just like the default constructor. */
        return;
    }

    /*
      We can't assign directly to m_atomicValue, because the
      temporary will self-destruct before we've ref'd it.
    */
    const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));

    if(temp)
    {
        temp.asAtomicValue()->ref.ref();
        m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
        m_atomicValue = temp.asAtomicValue();
    }
    else
    {
        m_atomicValue = 0;
    }
}

/*!
  Constructs a node QXmlItem that is a copy of \a node.

  \sa isNode()
 */
QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
{
}


/*!
  Destructor.
 */
QXmlItem::~QXmlItem()
{
    if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
        delete m_atomicValue;
}

bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const
{
    return data != other.data
           || additionalData != other.additionalData
           || model != other.model;
}

/*!
  Assigns \a other to \c this.
 */
QXmlItem &QXmlItem::operator=(const QXmlItem &other)
{
    if(m_node != other.m_node)
    {
        if(internalIsAtomicValue() && !m_atomicValue->ref.deref())
            delete m_atomicValue;

        m_node = other.m_node;

        if(internalIsAtomicValue())
            m_atomicValue->ref.ref();
    }

    return *this;
}

/*!
  Returns true if this item is a Node. Returns false if it
  is an atomic value or null.

  \sa isNull(), isAtomicValue()
 */
bool QXmlItem::isNode() const
{
    return QPatternist::Item::fromPublic(*this).isNode();
}

/*!
  Returns true if this item is an atomic value. Returns false
  if it is a node or null.

  \sa isNull(), isNode()
 */
bool QXmlItem::isAtomicValue() const
{
    return internalIsAtomicValue();
}

/*!
  If this QXmlItem represents an atomic value, it is converted
  to an appropriate QVariant and returned. If this QXmlItem is
  not an atomic value, the return value is a default constructed
  QVariant. You can call isAtomicValue() to test whether the
  item is an atomic value.

 \sa isAtomicValue()
 */
QVariant QXmlItem::toAtomicValue() const
{
    if(isAtomicValue())
        return QPatternist::AtomicValue::toQt(m_atomicValue);
    else
        return QVariant();
}

/*!
  If this QXmlItem represents a node, it returns the item as a
  QXmlNodeModelIndex. If this QXmlItem is not a node, the return
  value is undefined. You can call isNode() to test whether the
  item is a node.

 \sa isNode()
 */
QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const
{
    if(isNode())
        return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
    else
        return QXmlNodeModelIndex();
}

/*!
  Returns true if this QXmlItem is neither a node nor an
  atomic value. Default constructed instances of QXmlItem
  are null.
 */
bool QXmlItem::isNull() const
{
    return !m_node.model;
}

/*!
  \class QXmlNodeModelIndex
  \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel.
  \reentrant
  \since 4.4
  \ingroup xml-tools
  \inmodule QtXmlPatterns

  QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel}
  {XML node model}. It contains:

  \list
    \li A pointer to an \l{QAbstractXmlNodeModel} {XML node model},
    which is returned by model(), and
    \li Some data, which is returned by data(), internalPointer(),
    and additionalData().
  \endlist

  Because QXmlNodeModelIndex is intentionally a simple class, it
  doesn't have member functions for accessing the properties of
  nodes. For example, it doesn't have functions for getting a
  node's name or its list of attributes or child nodes. If you find
  that you need to retrieve this kind of information from your
  query results, there are two ways to proceed.

  \list

  \li Send the output of your XQuery to an \l{QAbstractXmlReceiver}
  {XML receiver}, or

  \li Let your XQuery do all the work to produce the desired result.

  \endlist

  The second case is explained by example. Suppose you want to
  populate a list widget with the values of certain attributes from a
  set of result elements. You could write an XQuery to return the set
  of elements, and then you would write the code to iterate over the
  result elements, get their attributes, and extract the desired
  string values. But the simpler way is to just augment your XQuery to
  finding the desired attribute values. Then all you have to do is
  evaluate the XQuery using the version of QXmlQuery::evaluateTo()
  that populates a QStringList, which you can send directly to your
  widget.

  QXmlNodeModelIndex doesn't impose any restrictions on the \c data
  value an QXmlNodeModelIndex should contain. The meaning of the data
  left to the associated \l {QAbstractXmlNodeModel} {node model}.
  Because QXmlNodeModelIndex depends on a particular subclass of
  QAbstractXmlNodeModel for its existence, the only way you can create
  an instance of QXmlNodeModelIndex is by asking the node model to
  create one for you with QAbstractXmlNodeModel::createIndex(). Since
  that function is protected, it is usually a good idea to write a
  public function that creates a QXmlNodeModelIndex from arguments that
  are appropriate for your particular node model.

  A default constructed node index is said to be null, i.e., isNull()
  returns true.

  QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design
  pattern used for QModelIndex and QAbstractItemModel.
 */

/*!
  \since 4.4
  \relates QHash

  Computes a hash key from the QXmlNodeModelIndex \a index, and
  returns it. This function would be used by QHash if you wanted
  to build a hash table for instances of QXmlNodeModelIndex.

  The hash is computed on QXmlNodeModelIndex::data(),
  QXmlNodeModelIndex::additionalData(), and
  QXmlNodeModelIndex::model(). This means the hash key can be used for
  node indexes from different node models.
 */
uint qHash(const QXmlNodeModelIndex &index)
{
    return uint(index.data() + index.additionalData() + quintptr(index.model()));
}

/*!
  \enum QXmlNodeModelIndex::NodeKind

  Identifies a kind of node.

  \value Attribute Identifies an attribute node
  \value Text Identifies a text node
  \value Comment Identifies a comment node
  \value Document Identifies a document node
  \value Element Identifies an element node
  \value Namespace Identifies a namespace node
  \value ProcessingInstruction Identifies a processing instruction.

  Note that the optional XML declaration at very beginning of the XML
  document is not a processing instruction

  \sa QAbstractXmlNodeModel::kind()
*/

/*!
 \typedef QXmlNodeModelIndex::List

 Typedef for QList<QXmlNodeModelIndex>.
 */

/*!
  Returns true if this node is the same as \a other. This operator
  does not compare values, children, or names of nodes. It compares
  node identities, i.e., whether two nodes are from the same document
  and are found at the exact same place.
 */
bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const
{
    return !(m_storage != other.m_storage);
}

/*!
  Returns true if \a other is the same node as this.
 */
bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const
{
    return !(operator==(other));
}

/*!
 \fn QXmlNodeModelIndex::QXmlNodeModelIndex()

 Default constructor. Creates an item that is \c null.

 \sa isNull()
 */

/*!
 \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other)

 Standard copy constructor. Creates a QXmlNodeModelIndex instance that
 is a copy of \a other.
 */

/*!
 \fn bool QXmlNodeModelIndex::isNull() const

 Returns true if this QXmlNodeModelIndex is a default constructed
 value, otherwise false.

 A null QXmlNodeModelIndex doesn't represent any node and cannot
 be used in conjunction with QAbstractXmlNodeModel.
 */

/*!
 \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const

 Returns the QAbstractXmlNodeModel that this node index refers to.
 QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not
 keep track of its lifetime, so this pointer will dangle if the
 QAbstractXmlNodeModel is deallocated first.

 There is no setter for the node model because instances of
 QXmlNodeModelIndex instances are only created with
 QAbstractXmlNodeModel::createIndex().
*/

/*!
 \fn qint64 QXmlNodeModelIndex::data() const

 Returns the first data value. The node index holds two data values.
 additionalData() returns the second one.

 \sa additionalData()
*/

/*!
 \fn void *QXmlNodeModelIndex::internalPointer() const

 Returns the first data value as a void* pointer.

 \sa additionalData()
*/

/*!
 \fn qint64 QXmlNodeModelIndex::additionalData() const

 Returns the second data value. The node index holds two data values.
 data() returns the first one.

 \sa data()
*/

/*!
 \fn void QXmlNodeModelIndex::reset()
 \internal

 Resets this QXmlNodeModelIndex to be null. It is equivalent to
 writing:

 \snippet code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0
 */

/*!
 \fn QXmlName QXmlNodeModelIndex::name() const
 \internal
*/

/*!
 \typedef QXmlNodeModelIndex::Iterator
 \internal

 Typedef for QAbstractXmlForwardIterator<QXmlNodeModelIndex>.
 */
/*!
 \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const
 \internal
*/

/*!
 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QXmlNodeModelIndex> > QXmlNodeModelIndex::iterate(const Axis axis) const
 \internal
*/

/*!
 \fn QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<QPatternist::Item> > QXmlNodeModelIndex::sequencedTypedValue() const
 \internal
*/

/*!
 \fn QUrl QXmlNodeModelIndex::documentUri() const
 \internal
*/

/*!
 \fn QUrl QXmlNodeModelIndex::baseUri() const
 \internal
*/

/*!
 \fn NodeKind QXmlNodeModelIndex::kind() const
 \internal
*/

/*!
 \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const
 \internal
*/

/*!
 \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const
 \internal
*/

/*!
 \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const
 \internal
*/

/*!
 \fn QVector<QXmlName> QXmlNodeModelIndex::namespaceBindings() const
 \internal
*/

/*!
 \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const

 Returns the index of the element identified as \a id. XQuery's \c
 id() function calls this function.

 The node index returned will be the element node whose value is of
 type \c ID and equals \a id, or it will be the element node that has
 an attribute whose typed value is of type \c ID and equals \a id. If
 there is no such element, a default constructed QXmlNodeModelIndex
 instance is returned. The implementor guarantees that if the returned
 node index is not null, it identifies an element.

 It is not sufficient for an attribute or element to merely be called
 \c id. Its value type must also be \c ID. However, the reserved name
 \c xml:id is sufficient.

 In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and
 the \c{local name} is the ID that should be looked up.

 \sa {http://www.w3.org/TR/xpath-functions/#func-id}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.2 fn:id}
 */

/*!
 \fn QVector<QXmlNodeModelIndex> QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const

 Returns the elements and/or attributes that have an \c IDREF value
 equal to \a idref. XQuery's \c idref() function calls this function.

 The implementor guarantees that the nodes identified by the returned
 indexes are elements or attributes.

 It is not sufficient for an attribute or element to merely be called
 \c idref. It must also be of type \c IDREF. Elements must be typed as
 \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c
 IDREF or \c IDREFS in the schema.

 In \a idref, the \c{namespace URI} and the \c{prefix} are undefined,
 and the \c{local name} is the ID that should be looked up.

 \sa {http://www.w3.org/TR/xpath-functions/#func-idref}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.3 fn:idref}
 */

/*!
 \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const
 \internal
*/

/*!
 \fn QString QXmlNodeModelIndex::stringValue() const
 \internal
*/

/*!
 \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const
 \internal
*/

/*!
 \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const
 \internal
*/

/*!
 \enum QAbstractXmlNodeModel::NodeCopySetting
 \internal

 Controls how nodes are copied with copyNodeTo.

 \value InheritNamespaces Copies the node with the \c copy-namespaces
        setting being \c inherit. If not set, \c no-inherit is assumed.
 \value PreserveNamespaces Copies the node with the \c copy-namespaces
        settings being \c preserve. If not set, \c no-preserve is assumed.
 */

/*!
 \typedef QAbstractXmlNodeModel::NodeCopySettings
 \internal
 */

/*!
 \internal

 Copies node \a node to \a receiver, steered by \a copySettings.

 The caller guarantees that \a node is not \c null, and that is
 belongs to this QAbstractXmlNodeModel instance.

 The caller guarantees that \a receiver is not \c null.
*/
void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node,
                                       QAbstractXmlReceiver *const receiver,
                                       const NodeCopySettings &copySettings) const
{
    Q_UNUSED(node);
    Q_UNUSED(receiver);
    Q_UNUSED(copySettings);
    Q_ASSERT_X(false, Q_FUNC_INFO,
               "This function is not expected to be called.");
}

/*!
    Returns the source location for the object with the given \a index
    or a default constructed QSourceLocation in case no location
    information is available.

    \since 4.6
*/
QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const
{
    // TODO: make this method virtual in Qt5 to allow source location support in custom models
    if (d_ptr)
        return d_ptr->sourceLocation(index);
    else
        return QSourceLocation();
}

QT_END_NAMESPACE
