/*
 *    XPath/XSLPattern query result node list implementation
 *
 * Copyright 2005 Mike McCormack
 * Copyright 2007 Mikolaj Zalewski
 * Copyright 2010 Adam Martinson for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include "config.h"

#include <stdarg.h>
#ifdef HAVE_LIBXML2
# include <libxml/parser.h>
# include <libxml/xmlerror.h>
# include <libxml/xpath.h>
# include <libxml/xpathInternals.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "msxml6.h"
#include "msxml2did.h"

#include "msxml_private.h"

#include "wine/debug.h"

/* This file implements the object returned by a XPath query. Note that this is
 * not the IXMLDOMNodeList returned by childNodes - it's implemented in nodelist.c.
 * They are different because the list returned by XPath queries:
 *  - is static - gives the results for the XML tree as it existed during the
 *    execution of the query
 *  - supports IXMLDOMSelection
 *
 */

#ifdef HAVE_LIBXML2

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

int registerNamespaces(xmlXPathContextPtr ctxt);
xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str);

typedef struct
{
    IEnumVARIANT IEnumVARIANT_iface;
    LONG ref;

    IUnknown *outer;
    BOOL own;

    LONG pos;

    const struct enumvariant_funcs *funcs;
} enumvariant;

typedef struct
{
    DispatchEx dispex;
    IXMLDOMSelection IXMLDOMSelection_iface;
    LONG ref;
    xmlNodePtr node;
    xmlXPathObjectPtr result;
    int resultPos;
    IEnumVARIANT *enumvariant;
} domselection;

static HRESULT selection_get_item(IUnknown *iface, LONG index, VARIANT* item)
{
    V_VT(item) = VT_DISPATCH;
    return IXMLDOMSelection_get_item((IXMLDOMSelection*)iface, index, (IXMLDOMNode**)&V_DISPATCH(item));
}

static HRESULT selection_next(IUnknown *iface)
{
    IXMLDOMNode *node;
    HRESULT hr = IXMLDOMSelection_nextNode((IXMLDOMSelection*)iface, &node);
    if (hr == S_OK) IXMLDOMNode_Release(node);
    return hr;
}

static const struct enumvariant_funcs selection_enumvariant = {
    selection_get_item,
    selection_next
};

static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface )
{
    return CONTAINING_RECORD(iface, domselection, IXMLDOMSelection_iface);
}

static inline enumvariant *impl_from_IEnumVARIANT( IEnumVARIANT *iface )
{
    return CONTAINING_RECORD(iface, enumvariant, IEnumVARIANT_iface);
}

static HRESULT WINAPI domselection_QueryInterface(
    IXMLDOMSelection *iface,
    REFIID riid,
    void** ppvObject )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);

    if(!ppvObject)
        return E_INVALIDARG;

    if ( IsEqualGUID( riid, &IID_IUnknown ) ||
         IsEqualGUID( riid, &IID_IXMLDOMNodeList ) ||
         IsEqualGUID( riid, &IID_IXMLDOMSelection ))
    {
        *ppvObject = &This->IXMLDOMSelection_iface;
    }
    else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
    {
        if (!This->enumvariant)
        {
            HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &selection_enumvariant, &This->enumvariant);
            if (FAILED(hr)) return hr;
        }

        return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject);
    }
    else if (dispex_query_interface(&This->dispex, riid, ppvObject))
    {
        return *ppvObject ? S_OK : E_NOINTERFACE;
    }
    else
    {
        TRACE("interface %s not implemented\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IXMLDOMSelection_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI domselection_AddRef(
    IXMLDOMSelection *iface )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI domselection_Release(
    IXMLDOMSelection *iface )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);
    if ( ref == 0 )
    {
        xmlXPathFreeObject(This->result);
        xmldoc_release(This->node->doc);
        if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI domselection_GetTypeInfoCount(
    IXMLDOMSelection *iface,
    UINT* pctinfo )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI domselection_GetTypeInfo(
    IXMLDOMSelection *iface,
    UINT iTInfo,
    LCID lcid,
    ITypeInfo** ppTInfo )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
        iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI domselection_GetIDsOfNames(
    IXMLDOMSelection *iface,
    REFIID riid,
    LPOLESTR* rgszNames,
    UINT cNames,
    LCID lcid,
    DISPID* rgDispId )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
        riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI domselection_Invoke(
    IXMLDOMSelection *iface,
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS* pDispParams,
    VARIANT* pVarResult,
    EXCEPINFO* pExcepInfo,
    UINT* puArgErr )
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI domselection_get_item(
        IXMLDOMSelection* iface,
        LONG index,
        IXMLDOMNode** listItem)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("(%p)->(%d %p)\n", This, index, listItem);

    if(!listItem)
        return E_INVALIDARG;

    *listItem = NULL;

    if (index < 0 || index >= xmlXPathNodeSetGetLength(This->result->nodesetval))
        return S_FALSE;

    *listItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, index));
    This->resultPos = index + 1;

    return S_OK;
}

static HRESULT WINAPI domselection_get_length(
        IXMLDOMSelection* iface,
        LONG* listLength)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("(%p)->(%p)\n", This, listLength);

    if(!listLength)
        return E_INVALIDARG;

    *listLength = xmlXPathNodeSetGetLength(This->result->nodesetval);
    return S_OK;
}

static HRESULT WINAPI domselection_nextNode(
        IXMLDOMSelection* iface,
        IXMLDOMNode** nextItem)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("(%p)->(%p)\n", This, nextItem );

    if(!nextItem)
        return E_INVALIDARG;

    *nextItem = NULL;

    if (This->resultPos >= xmlXPathNodeSetGetLength(This->result->nodesetval))
        return S_FALSE;

    *nextItem = create_node(xmlXPathNodeSetItem(This->result->nodesetval, This->resultPos));
    This->resultPos++;
    return S_OK;
}

static HRESULT WINAPI domselection_reset(
        IXMLDOMSelection* iface)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("%p\n", This);
    This->resultPos = 0;
    return S_OK;
}

static HRESULT WINAPI domselection_get__newEnum(
        IXMLDOMSelection* iface,
        IUnknown** enumv)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );

    TRACE("(%p)->(%p)\n", This, enumv);

    return create_enumvariant((IUnknown*)iface, TRUE, &selection_enumvariant, (IEnumVARIANT**)enumv);
}

static HRESULT WINAPI domselection_get_expr(
        IXMLDOMSelection* iface,
        BSTR *p)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_put_expr(
        IXMLDOMSelection* iface,
        BSTR p)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%s)\n", This, debugstr_w(p));
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_get_context(
        IXMLDOMSelection* iface,
        IXMLDOMNode **node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_putref_context(
        IXMLDOMSelection* iface,
        IXMLDOMNode *node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_peekNode(
        IXMLDOMSelection* iface,
        IXMLDOMNode **node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_matches(
        IXMLDOMSelection* iface,
        IXMLDOMNode *node,
        IXMLDOMNode **out_node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p %p)\n", This, node, out_node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_removeNext(
        IXMLDOMSelection* iface,
        IXMLDOMNode **node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_removeAll(
        IXMLDOMSelection* iface)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_clone(
        IXMLDOMSelection* iface,
        IXMLDOMSelection **node)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%p)\n", This, node);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_getProperty(
        IXMLDOMSelection* iface,
        BSTR p,
        VARIANT *var)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(p), var);
    return E_NOTIMPL;
}

static HRESULT WINAPI domselection_setProperty(
        IXMLDOMSelection* iface,
        BSTR p,
        VARIANT var)
{
    domselection *This = impl_from_IXMLDOMSelection( iface );
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(p), debugstr_variant(&var));
    return E_NOTIMPL;
}

static const struct IXMLDOMSelectionVtbl domselection_vtbl =
{
    domselection_QueryInterface,
    domselection_AddRef,
    domselection_Release,
    domselection_GetTypeInfoCount,
    domselection_GetTypeInfo,
    domselection_GetIDsOfNames,
    domselection_Invoke,
    domselection_get_item,
    domselection_get_length,
    domselection_nextNode,
    domselection_reset,
    domselection_get__newEnum,
    domselection_get_expr,
    domselection_put_expr,
    domselection_get_context,
    domselection_putref_context,
    domselection_peekNode,
    domselection_matches,
    domselection_removeNext,
    domselection_removeAll,
    domselection_clone,
    domselection_getProperty,
    domselection_setProperty
};

/* IEnumVARIANT support */
static HRESULT WINAPI enumvariant_QueryInterface(
    IEnumVARIANT *iface,
    REFIID riid,
    void** ppvObject )
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );

    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);

    *ppvObject = NULL;

    if (IsEqualGUID( riid, &IID_IUnknown ))
    {
        if (This->own)
            *ppvObject = &This->IEnumVARIANT_iface;
        else
            return IUnknown_QueryInterface(This->outer, riid, ppvObject);
    }
    else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
    {
        *ppvObject = &This->IEnumVARIANT_iface;
    }
    else
        return IUnknown_QueryInterface(This->outer, riid, ppvObject);

    IEnumVARIANT_AddRef( iface );

    return S_OK;
}

static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface )
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    ULONG ref = InterlockedIncrement( &This->ref );
    TRACE("(%p)->(%d)\n", This, ref);
    return ref;
}

static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(%d)\n", This, ref);
    if ( ref == 0 )
    {
        if (This->own) IUnknown_Release(This->outer);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI enumvariant_Next(
    IEnumVARIANT *iface,
    ULONG celt,
    VARIANT *var,
    ULONG *fetched)
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    ULONG ret_count = 0;

    TRACE("(%p)->(%u %p %p)\n", This, celt, var, fetched);

    if (fetched) *fetched = 0;

    if (celt && !var) return E_INVALIDARG;

    for (; celt > 0; celt--, var++, This->pos++)
    {
        HRESULT hr = This->funcs->get_item(This->outer, This->pos, var);
        if (hr != S_OK)
        {
            V_VT(var) = VT_EMPTY;
            break;
        }
        ret_count++;
    }

    if (fetched) (*fetched)++;

    /* we need to advance one step more for some reason */
    if (ret_count)
    {
        if (This->funcs->next)
            This->funcs->next(This->outer);
    }

    return celt == 0 ? S_OK : S_FALSE;
}

static HRESULT WINAPI enumvariant_Skip(
    IEnumVARIANT *iface,
    ULONG celt)
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    FIXME("(%p)->(%u): stub\n", This, celt);
    return E_NOTIMPL;
}

static HRESULT WINAPI enumvariant_Reset(IEnumVARIANT *iface)
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    FIXME("(%p): stub\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI enumvariant_Clone(
    IEnumVARIANT *iface, IEnumVARIANT **ppenum)
{
    enumvariant *This = impl_from_IEnumVARIANT( iface );
    FIXME("(%p)->(%p): stub\n", This, ppenum);
    return E_NOTIMPL;
}

static const struct IEnumVARIANTVtbl EnumVARIANTVtbl =
{
    enumvariant_QueryInterface,
    enumvariant_AddRef,
    enumvariant_Release,
    enumvariant_Next,
    enumvariant_Skip,
    enumvariant_Reset,
    enumvariant_Clone
};

HRESULT create_enumvariant(IUnknown *outer, BOOL own, const struct enumvariant_funcs *funcs, IEnumVARIANT **penum)
{
    enumvariant *This;

    This = heap_alloc(sizeof(enumvariant));
    if (!This) return E_OUTOFMEMORY;

    This->IEnumVARIANT_iface.lpVtbl = &EnumVARIANTVtbl;
    This->ref = 0;
    This->outer = outer;
    This->own = own;
    This->pos = 0;
    This->funcs = funcs;

    if (This->own)
        IUnknown_AddRef(This->outer);

    *penum = &This->IEnumVARIANT_iface;
    IEnumVARIANT_AddRef(*penum);
    return S_OK;
}

static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
{
    WCHAR *ptr;
    int idx = 0;

    for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
        idx = idx*10 + (*ptr-'0');
    if(*ptr)
        return DISP_E_UNKNOWNNAME;

    *dispid = DISPID_DOM_COLLECTION_BASE + idx;
    TRACE("ret %x\n", *dispid);
    return S_OK;
}

static HRESULT domselection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
        VARIANT *res, EXCEPINFO *ei)
{
    domselection *This = impl_from_IXMLDOMSelection( (IXMLDOMSelection*)iface );

    TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);

    V_VT(res) = VT_DISPATCH;
    V_DISPATCH(res) = NULL;

    if (id < DISPID_DOM_COLLECTION_BASE || id > DISPID_DOM_COLLECTION_MAX)
        return DISP_E_UNKNOWNNAME;

    switch(flags)
    {
        case INVOKE_PROPERTYGET:
        {
            IXMLDOMNode *disp = NULL;

            IXMLDOMSelection_get_item(&This->IXMLDOMSelection_iface, id - DISPID_DOM_COLLECTION_BASE, &disp);
            V_DISPATCH(res) = (IDispatch*)disp;
            break;
        }
        default:
        {
            FIXME("unimplemented flags %x\n", flags);
            break;
        }
    }

    TRACE("ret %p\n", V_DISPATCH(res));

    return S_OK;
}

static const dispex_static_data_vtbl_t domselection_dispex_vtbl = {
    domselection_get_dispid,
    domselection_invoke
};

static const tid_t domselection_iface_tids[] = {
    IXMLDOMSelection_tid,
    0
};
static dispex_static_data_t domselection_dispex = {
    &domselection_dispex_vtbl,
    IXMLDOMSelection_tid,
    NULL,
    domselection_iface_tids
};

#define XSLPATTERN_CHECK_ARGS(n) \
    if (nargs != n) { \
        FIXME("XSLPattern syntax error: Expected %i arguments, got %i\n", n, nargs); \
        xmlXPathSetArityError(pctx); \
        return; \
    }


static void XSLPattern_index(xmlXPathParserContextPtr pctx, int nargs)
{
    XSLPATTERN_CHECK_ARGS(0);

    xmlXPathPositionFunction(pctx, 0);
    xmlXPathReturnNumber(pctx, xmlXPathPopNumber(pctx) - 1.0);
}

static void XSLPattern_end(xmlXPathParserContextPtr pctx, int nargs)
{
    double pos, last;
    XSLPATTERN_CHECK_ARGS(0);

    xmlXPathPositionFunction(pctx, 0);
    pos = xmlXPathPopNumber(pctx);
    xmlXPathLastFunction(pctx, 0);
    last = xmlXPathPopNumber(pctx);
    xmlXPathReturnBoolean(pctx, pos == last);
}

static void XSLPattern_nodeType(xmlXPathParserContextPtr pctx, int nargs)
{
    XSLPATTERN_CHECK_ARGS(0);
    xmlXPathReturnNumber(pctx, pctx->context->node->type);
}

static void XSLPattern_OP_IEq(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) == 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void XSLPattern_OP_INEq(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) != 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void XSLPattern_OP_ILt(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) < 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void XSLPattern_OP_ILEq(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) <= 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void XSLPattern_OP_IGt(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) > 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void XSLPattern_OP_IGEq(xmlXPathParserContextPtr pctx, int nargs)
{
    xmlChar *arg1, *arg2;
    XSLPATTERN_CHECK_ARGS(2);

    arg2 = xmlXPathPopString(pctx);
    arg1 = xmlXPathPopString(pctx);
    xmlXPathReturnBoolean(pctx, xmlStrcasecmp(arg1, arg2) >= 0);
    xmlFree(arg1);
    xmlFree(arg2);
}

static void query_serror(void* ctx, xmlErrorPtr err)
{
    LIBXML2_CALLBACK_SERROR(domselection_create, err);
}

HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
{
    domselection *This = heap_alloc(sizeof(domselection));
    xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", node, debugstr_a((char const*)query), out);

    *out = NULL;
    if (!This || !ctxt || !query)
    {
        xmlXPathFreeContext(ctxt);
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl;
    This->ref = 1;
    This->resultPos = 0;
    This->node = node;
    This->enumvariant = NULL;
    init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex);
    xmldoc_add_ref(This->node->doc);

    ctxt->error = query_serror;
    ctxt->node = node;
    registerNamespaces(ctxt);

    if (is_xpathmode(This->node->doc))
    {
        xmlXPathRegisterAllFunctions(ctxt);
        This->result = xmlXPathEvalExpression(query, ctxt);
    }
    else
    {
        xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, query);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq);

        This->result = xmlXPathEvalExpression(pattern_query, ctxt);
        xmlFree(pattern_query);
    }

    if (!This->result || This->result->type != XPATH_NODESET)
    {
        hr = E_FAIL;
        goto cleanup;
    }

    *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface;
    hr = S_OK;
    TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));

cleanup:
    if (This && FAILED(hr))
        IXMLDOMSelection_Release( &This->IXMLDOMSelection_iface );
    xmlXPathFreeContext(ctxt);
    return hr;
}

#endif
