/*
 *    DOM Document implementation
 *
 * Copyright 2005 Mike McCormack
 *
 * 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>
#endif

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

#include "msxml_private.h"

#include "wine/debug.h"

#ifdef HAVE_LIBXML2

WINE_DEFAULT_DEBUG_CHANNEL(msxml);

static const xmlChar DT_prefix[] = "dt";
static const xmlChar DT_nsURI[] = "urn:schemas-microsoft-com:datatypes";

typedef struct _domelem
{
    xmlnode node;
    IXMLDOMElement IXMLDOMElement_iface;
    LONG ref;
} domelem;

static const struct nodemap_funcs domelem_attr_map;

static const tid_t domelem_se_tids[] = {
    IXMLDOMNode_tid,
    IXMLDOMElement_tid,
    NULL_tid
};

static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
{
    return CONTAINING_RECORD(iface, domelem, IXMLDOMElement_iface);
}

static inline xmlNodePtr get_element( const domelem *This )
{
    return This->node.node;
}

static HRESULT WINAPI domelem_QueryInterface(
    IXMLDOMElement *iface,
    REFIID riid,
    void** ppvObject )
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
         IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
         IsEqualGUID( riid, &IID_IDispatch ) ||
         IsEqualGUID( riid, &IID_IUnknown ) )
    {
        *ppvObject = &This->IXMLDOMElement_iface;
    }
    else if(node_query_interface(&This->node, riid, ppvObject))
    {
        return *ppvObject ? S_OK : E_NOINTERFACE;
    }
    else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
    {
        return node_create_supporterrorinfo(domelem_se_tids, ppvObject);
    }
    else
    {
        TRACE("interface %s not implemented\n", debugstr_guid(riid));
        *ppvObject = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef( (IUnknown*)*ppvObject );
    return S_OK;
}

static ULONG WINAPI domelem_AddRef(
    IXMLDOMElement *iface )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    LONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI domelem_Release(
    IXMLDOMElement *iface )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if(!ref) {
        destroy_xmlnode(&This->node);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI domelem_GetTypeInfoCount(
    IXMLDOMElement *iface,
    UINT* pctinfo )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo);
}

static HRESULT WINAPI domelem_GetTypeInfo(
    IXMLDOMElement *iface,
    UINT iTInfo, LCID lcid,
    ITypeInfo** ppTInfo )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface,
        iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI domelem_GetIDsOfNames(
    IXMLDOMElement *iface,
    REFIID riid, LPOLESTR* rgszNames,
    UINT cNames, LCID lcid, DISPID* rgDispId )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface,
        riid, rgszNames, cNames, lcid, rgDispId);
}

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

static HRESULT WINAPI domelem_get_nodeName(
    IXMLDOMElement *iface,
    BSTR* p )
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_nodeName(&This->node, p);
}

static HRESULT WINAPI domelem_get_nodeValue(
    IXMLDOMElement *iface,
    VARIANT* value)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    if(!value)
        return E_INVALIDARG;

    V_VT(value) = VT_NULL;
    V_BSTR(value) = NULL; /* tests show that we should do this */
    return S_FALSE;
}

static HRESULT WINAPI domelem_put_nodeValue(
    IXMLDOMElement *iface,
    VARIANT value)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
    return E_FAIL;
}

static HRESULT WINAPI domelem_get_nodeType(
    IXMLDOMElement *iface,
    DOMNodeType* domNodeType )
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    *domNodeType = NODE_ELEMENT;
    return S_OK;
}

static HRESULT WINAPI domelem_get_parentNode(
    IXMLDOMElement *iface,
    IXMLDOMNode** parent )
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_parent(&This->node, parent);
}

static HRESULT WINAPI domelem_get_childNodes(
    IXMLDOMElement *iface,
    IXMLDOMNodeList** outList)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_child_nodes(&This->node, outList);
}

static HRESULT WINAPI domelem_get_firstChild(
    IXMLDOMElement *iface,
    IXMLDOMNode** domNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_first_child(&This->node, domNode);
}

static HRESULT WINAPI domelem_get_lastChild(
    IXMLDOMElement *iface,
    IXMLDOMNode** domNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_last_child(&This->node, domNode);
}

static HRESULT WINAPI domelem_get_previousSibling(
    IXMLDOMElement *iface,
    IXMLDOMNode** domNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_previous_sibling(&This->node, domNode);
}

static HRESULT WINAPI domelem_get_nextSibling(
    IXMLDOMElement *iface,
    IXMLDOMNode** domNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_next_sibling(&This->node, domNode);
}

static HRESULT WINAPI domelem_get_attributes(
    IXMLDOMElement *iface,
    IXMLDOMNamedNodeMap** map)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    *map = create_nodemap(This->node.node, &domelem_attr_map);
    return S_OK;
}

static HRESULT WINAPI domelem_insertBefore(
    IXMLDOMElement *iface,
    IXMLDOMNode* newNode, VARIANT refChild,
    IXMLDOMNode** old_node)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    DOMNodeType type;
    HRESULT hr;

    TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), old_node);

    hr = IXMLDOMNode_get_nodeType(newNode, &type);
    if (hr != S_OK) return hr;

    TRACE("new node type %d\n", type);
    switch (type)
    {
        case NODE_DOCUMENT:
        case NODE_DOCUMENT_TYPE:
        case NODE_ENTITY:
        case NODE_NOTATION:
            if (old_node) *old_node = NULL;
            return E_FAIL;
        default:
            return node_insert_before(&This->node, newNode, &refChild, old_node);
    }
}

static HRESULT WINAPI domelem_replaceChild(
    IXMLDOMElement *iface,
    IXMLDOMNode* newNode,
    IXMLDOMNode* oldNode,
    IXMLDOMNode** outOldNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

    TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode);

    return node_replace_child(&This->node, newNode, oldNode, outOldNode);
}

static HRESULT WINAPI domelem_removeChild(
    IXMLDOMElement *iface,
    IXMLDOMNode *child, IXMLDOMNode **oldChild)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p %p)\n", This, child, oldChild);
    return node_remove_child(&This->node, child, oldChild);
}

static HRESULT WINAPI domelem_appendChild(
    IXMLDOMElement *iface,
    IXMLDOMNode *child, IXMLDOMNode **outChild)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p %p)\n", This, child, outChild);
    return node_append_child(&This->node, child, outChild);
}

static HRESULT WINAPI domelem_hasChildNodes(
    IXMLDOMElement *iface,
    VARIANT_BOOL *ret)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, ret);
    return node_has_childnodes(&This->node, ret);
}

static HRESULT WINAPI domelem_get_ownerDocument(
    IXMLDOMElement   *iface,
    IXMLDOMDocument **doc)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, doc);
    return node_get_owner_doc(&This->node, doc);
}

static HRESULT WINAPI domelem_cloneNode(
    IXMLDOMElement *iface,
    VARIANT_BOOL deep, IXMLDOMNode** outNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%d %p)\n", This, deep, outNode);
    return node_clone( &This->node, deep, outNode );
}

static HRESULT WINAPI domelem_get_nodeTypeString(
    IXMLDOMElement *iface,
    BSTR* p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    static const WCHAR elementW[] = {'e','l','e','m','e','n','t',0};

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

    return return_bstr(elementW, p);
}

static HRESULT WINAPI domelem_get_text(
    IXMLDOMElement *iface,
    BSTR* p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, p);
    return node_get_text(&This->node, p);
}

static HRESULT WINAPI domelem_put_text(
    IXMLDOMElement *iface,
    BSTR p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%s)\n", This, debugstr_w(p));
    return node_put_text( &This->node, p );
}

static HRESULT WINAPI domelem_get_specified(
    IXMLDOMElement *iface,
    VARIANT_BOOL* isSpecified)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("(%p)->(%p) stub!\n", This, isSpecified);
    *isSpecified = VARIANT_TRUE;
    return S_OK;
}

static HRESULT WINAPI domelem_get_definition(
    IXMLDOMElement *iface,
    IXMLDOMNode** definitionNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("(%p)->(%p)\n", This, definitionNode);
    return E_NOTIMPL;
}

static inline BYTE hex_to_byte(xmlChar c)
{
    if(c <= '9') return c-'0';
    if(c <= 'F') return c-'A'+10;
    return c-'a'+10;
}

static inline BYTE base64_to_byte(xmlChar c)
{
    if(c == '+') return 62;
    if(c == '/') return 63;
    if(c <= '9') return c-'0'+52;
    if(c <= 'Z') return c-'A';
    return c-'a'+26;
}

static inline HRESULT variant_from_dt(XDR_DT dt, xmlChar* str, VARIANT* v)
{
    VARIANT src;
    HRESULT hr = S_OK;
    BOOL handled = FALSE;

    VariantInit(&src);

    switch (dt)
    {
    case DT_INVALID:
    case DT_STRING:
    case DT_NMTOKEN:
    case DT_NMTOKENS:
    case DT_NUMBER:
    case DT_URI:
    case DT_UUID:
        {
            V_VT(v) = VT_BSTR;
            V_BSTR(v) = bstr_from_xmlChar(str);

            if(!V_BSTR(v))
                return E_OUTOFMEMORY;
            handled = TRUE;
        }
        break;
    case DT_DATE:
    case DT_DATE_TZ:
    case DT_DATETIME:
    case DT_DATETIME_TZ:
    case DT_TIME:
    case DT_TIME_TZ:
        {
            WCHAR *p, *e;
            SYSTEMTIME st;
            DOUBLE date = 0.0;

            st.wYear = 1899;
            st.wMonth = 12;
            st.wDay = 30;
            st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;

            V_VT(&src) = VT_BSTR;
            V_BSTR(&src) = bstr_from_xmlChar(str);

            if(!V_BSTR(&src))
                return E_OUTOFMEMORY;

            p = V_BSTR(&src);
            e = p + SysStringLen(V_BSTR(&src));

            if(p+4<e && *(p+4)=='-') /* parse date (yyyy-mm-dd) */
            {
                st.wYear = atoiW(p);
                st.wMonth = atoiW(p+5);
                st.wDay = atoiW(p+8);
                p += 10;

                if(*p == 'T') p++;
            }

            if(p+2<e && *(p+2)==':') /* parse time (hh:mm:ss.?) */
            {
                st.wHour = atoiW(p);
                st.wMinute = atoiW(p+3);
                st.wSecond = atoiW(p+6);
                p += 8;

                if(*p == '.')
                {
                    p++;
                    while(isdigitW(*p)) p++;
                }
            }

            SystemTimeToVariantTime(&st, &date);
            V_VT(v) = VT_DATE;
            V_DATE(v) = date;

            if(*p == '+') /* parse timezone offset (+hh:mm) */
                V_DATE(v) += (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;
            else if(*p == '-') /* parse timezone offset (-hh:mm) */
                V_DATE(v) -= (DOUBLE)atoiW(p+1)/24 + (DOUBLE)atoiW(p+4)/1440;

            VariantClear(&src);
            handled = TRUE;
        }
        break;
    case DT_BIN_HEX:
        {
            SAFEARRAYBOUND sab;
            int i, len;

            len = xmlStrlen(str)/2;
            sab.lLbound = 0;
            sab.cElements = len;

            V_VT(v) = (VT_ARRAY|VT_UI1);
            V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);

            if(!V_ARRAY(v))
                return E_OUTOFMEMORY;

            for(i=0; i<len; i++)
                ((BYTE*)V_ARRAY(v)->pvData)[i] = (hex_to_byte(str[2*i])<<4)
                    + hex_to_byte(str[2*i+1]);
            handled = TRUE;
        }
        break;
    case DT_BIN_BASE64:
        {
            SAFEARRAYBOUND sab;
            xmlChar *c1, *c2;
            int i, len;

            /* remove all formatting chars */
            c1 = c2 = str;
            len = 0;
            while (*c2)
            {
                if ( *c2 == ' '  || *c2 == '\t' ||
                     *c2 == '\n' || *c2 == '\r' )
                {
                    c2++;
                    continue;
                }
                *c1++ = *c2++;
                len++;
            }

            /* skip padding */
            if(str[len-2] == '=') i = 2;
            else if(str[len-1] == '=') i = 1;
            else i = 0;

            sab.lLbound = 0;
            sab.cElements = len/4*3-i;

            V_VT(v) = (VT_ARRAY|VT_UI1);
            V_ARRAY(v) = SafeArrayCreate(VT_UI1, 1, &sab);

            if(!V_ARRAY(v))
                return E_OUTOFMEMORY;

            for(i=0; i<len/4; i++)
            {
                ((BYTE*)V_ARRAY(v)->pvData)[3*i] = (base64_to_byte(str[4*i])<<2)
                    + (base64_to_byte(str[4*i+1])>>4);
                if(3*i+1 < sab.cElements)
                    ((BYTE*)V_ARRAY(v)->pvData)[3*i+1] = (base64_to_byte(str[4*i+1])<<4)
                        + (base64_to_byte(str[4*i+2])>>2);
                if(3*i+2 < sab.cElements)
                    ((BYTE*)V_ARRAY(v)->pvData)[3*i+2] = (base64_to_byte(str[4*i+2])<<6)
                        + base64_to_byte(str[4*i+3]);
            }
            handled = TRUE;
        }
        break;
    case DT_BOOLEAN:
        V_VT(v) = VT_BOOL;
        break;
    case DT_FIXED_14_4:
        V_VT(v) = VT_CY;
        break;
    case DT_I1:
        V_VT(v) = VT_I1;
        break;
    case DT_I2:
        V_VT(v) = VT_I2;
        break;
    case DT_I4:
    case DT_INT:
        V_VT(v) = VT_I4;
        break;
    case DT_I8:
        V_VT(v) = VT_I8;
        break;
    case DT_R4:
        V_VT(v) = VT_R4;
        break;
    case DT_FLOAT:
    case DT_R8:
        V_VT(v) = VT_R8;
        break;
    case DT_UI1:
        V_VT(v) = VT_UI1;
        break;
    case DT_UI2:
        V_VT(v) = VT_UI2;
        break;
    case DT_UI4:
        V_VT(v) = VT_UI4;
        break;
    case DT_UI8:
        V_VT(v) = VT_UI8;
        break;
    case DT_CHAR:
    case DT_ENTITY:
    case DT_ENTITIES:
    case DT_ENUMERATION:
    case DT_ID:
    case DT_IDREF:
    case DT_IDREFS:
    case DT_NOTATION:
        FIXME("need to handle dt:%s\n", debugstr_dt(dt));
        V_VT(v) = VT_BSTR;
        V_BSTR(v) = bstr_from_xmlChar(str);
        if (!V_BSTR(v))
            return E_OUTOFMEMORY;
        handled = TRUE;
        break;
    default:
        WARN("unknown type %d\n", dt);
    }

    if (!handled)
    {
        V_VT(&src) = VT_BSTR;
        V_BSTR(&src) = bstr_from_xmlChar(str);

        if(!V_BSTR(&src))
            return E_OUTOFMEMORY;

        hr = VariantChangeTypeEx(v, &src,
                MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT),0, V_VT(v));
        VariantClear(&src);
    }
    return hr;
}

static XDR_DT element_get_dt(xmlNodePtr node)
{
    XDR_DT dt = DT_INVALID;

    TRACE("(%p)\n", node);
    if(node->type != XML_ELEMENT_NODE)
    {
        FIXME("invalid element node\n");
        return dt;
    }

    if (node->ns && xmlStrEqual(node->ns->href, DT_nsURI))
    {
        dt = str_to_dt(node->name, -1);
    }
    else
    {
        xmlChar* pVal = xmlGetNsProp(node, BAD_CAST "dt", DT_nsURI);
        if (pVal)
        {
            dt = str_to_dt(pVal, -1);
            xmlFree(pVal);
        }
        else if (node->doc)
        {
            IXMLDOMDocument3* doc = (IXMLDOMDocument3*)create_domdoc((xmlNodePtr)node->doc);
            if (doc)
            {
                VARIANT v;
                VariantInit(&v);

                if (IXMLDOMDocument3_get_schemas(doc, &v) == S_OK &&
                    V_VT(&v) == VT_DISPATCH)
                {
                    dt = SchemaCache_get_node_dt((IXMLDOMSchemaCollection2*)V_DISPATCH(&v), node);
                }
                VariantClear(&v);
                IXMLDOMDocument3_Release(doc);
            }
        }
    }

    TRACE("=> dt:%s\n", debugstr_dt(dt));
    return dt;
}

static HRESULT WINAPI domelem_get_nodeTypedValue(
    IXMLDOMElement *iface,
    VARIANT* v)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    XDR_DT dt;
    xmlChar* content;
    HRESULT hr;

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

    if(!v) return E_INVALIDARG;

    V_VT(v) = VT_NULL;

    dt = element_get_dt(get_element(This));
    content = xmlNodeGetContent(get_element(This));
    hr = variant_from_dt(dt, content, v);
    xmlFree(content);

    return hr;
}

static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret)
{
    static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const BYTE *d = buf;
    int bytes, pad_bytes, div;
    DWORD needed;
    WCHAR *ptr;

    bytes = (len*8 + 5)/6;
    pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;

    TRACE("%d, bytes is %d, pad bytes is %d\n", len, bytes, pad_bytes);
    needed = bytes + pad_bytes + 1;

    *ret = SysAllocStringLen(NULL, needed);
    if (!*ret) return E_OUTOFMEMORY;

    /* Three bytes of input give 4 chars of output */
    div = len / 3;

    ptr = *ret;
    while (div > 0)
    {
        /* first char is the first 6 bits of the first byte*/
        *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
        /* second char is the last 2 bits of the first byte and the first 4
         * bits of the second byte */
        *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
        /* third char is the last 4 bits of the second byte and the first 2
         * bits of the third byte */
        *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
        /* fourth char is the remaining 6 bits of the third byte */
        *ptr++ = b64[   d[2]       & 0x3f];
        d += 3;
        div--;
    }

    switch (pad_bytes)
    {
        case 1:
            /* first char is the first 6 bits of the first byte*/
            *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
            /* second char is the last 2 bits of the first byte and the first 4
             * bits of the second byte */
            *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
            /* third char is the last 4 bits of the second byte padded with
             * two zeroes */
            *ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
            /* fourth char is a = to indicate one byte of padding */
            *ptr++ = '=';
            break;
        case 2:
            /* first char is the first 6 bits of the first byte*/
            *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
            /* second char is the last 2 bits of the first byte padded with
             * four zeroes*/
            *ptr++ = b64[ ((d[0] << 4) & 0x30)];
            /* third char is = to indicate padding */
            *ptr++ = '=';
            /* fourth char is = to indicate padding */
            *ptr++ = '=';
            break;
    }

    return S_OK;
}

static HRESULT encode_binhex(const BYTE *buf, int len, BSTR *ret)
{
    static const char byte_to_hex[16] = "0123456789abcdef";
    int i;

    *ret = SysAllocStringLen(NULL, len*2);
    if (!*ret) return E_OUTOFMEMORY;

    for (i = 0; i < len; i++)
    {
        (*ret)[2*i]   = byte_to_hex[buf[i] >> 4];
        (*ret)[2*i+1] = byte_to_hex[0x0f & buf[i]];
    }

    return S_OK;
}

static HRESULT WINAPI domelem_put_nodeTypedValue(
    IXMLDOMElement *iface,
    VARIANT value)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    XDR_DT dt;
    HRESULT hr;

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));

    dt = element_get_dt(get_element(This));
    switch (dt)
    {
    /* for untyped node coerce to BSTR and set */
    case DT_INVALID:
        if (V_VT(&value) != VT_BSTR)
        {
            VARIANT content;
            VariantInit(&content);
            hr = VariantChangeType(&content, &value, 0, VT_BSTR);
            if (hr == S_OK)
            {
                hr = node_set_content(&This->node, V_BSTR(&content));
                VariantClear(&content);
            }
        }
        else
            hr = node_set_content(&This->node, V_BSTR(&value));
        break;
    case DT_BIN_BASE64:
        if (V_VT(&value) == VT_BSTR)
            hr = node_set_content(&This->node, V_BSTR(&value));
        else if (V_VT(&value) == (VT_UI1|VT_ARRAY))
        {
            UINT dim = SafeArrayGetDim(V_ARRAY(&value));
            LONG lbound, ubound;
            BSTR encoded;
            BYTE *ptr;
            int len;

            if (dim > 1)
                FIXME("unexpected array dimension count %u\n", dim);

            SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
            SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);

            len = (ubound - lbound + 1)*SafeArrayGetElemsize(V_ARRAY(&value));

            hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
            if (FAILED(hr)) return hr;

            hr = encode_base64(ptr, len, &encoded);
            SafeArrayUnaccessData(V_ARRAY(&value));
            if (FAILED(hr)) return hr;

            hr = node_set_content(&This->node, encoded);
            SysFreeString(encoded);
        }
        else
        {
            FIXME("unhandled variant type %d for dt:%s\n", V_VT(&value), debugstr_dt(dt));
            return E_NOTIMPL;
        }
        break;
    case DT_BIN_HEX:
        if (V_VT(&value) == (VT_UI1|VT_ARRAY))
        {
            UINT dim = SafeArrayGetDim(V_ARRAY(&value));
            LONG lbound, ubound;
            BSTR encoded;
            BYTE *ptr;
            int len;

            if (dim > 1)
                FIXME("unexpected array dimension count %u\n", dim);

            SafeArrayGetUBound(V_ARRAY(&value), 1, &ubound);
            SafeArrayGetLBound(V_ARRAY(&value), 1, &lbound);

            len = (ubound - lbound + 1)*SafeArrayGetElemsize(V_ARRAY(&value));

            hr = SafeArrayAccessData(V_ARRAY(&value), (void*)&ptr);
            if (FAILED(hr)) return hr;

            hr = encode_binhex(ptr, len, &encoded);
            SafeArrayUnaccessData(V_ARRAY(&value));
            if (FAILED(hr)) return hr;

            hr = node_set_content(&This->node, encoded);
            SysFreeString(encoded);
        }
        else
        {
            FIXME("unhandled variant type %d for dt:%s\n", V_VT(&value), debugstr_dt(dt));
            return E_NOTIMPL;
        }
        break;
    default:
        FIXME("not implemented for dt:%s\n", debugstr_dt(dt));
        return E_NOTIMPL;
    }

    return hr;
}

static HRESULT WINAPI domelem_get_dataType(
    IXMLDOMElement *iface,
    VARIANT* typename)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    XDR_DT dt;

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

    if (!typename)
        return E_INVALIDARG;

    dt = element_get_dt(get_element(This));
    switch (dt)
    {
        case DT_BIN_BASE64:
        case DT_BIN_HEX:
        case DT_BOOLEAN:
        case DT_CHAR:
        case DT_DATE:
        case DT_DATE_TZ:
        case DT_DATETIME:
        case DT_DATETIME_TZ:
        case DT_FIXED_14_4:
        case DT_FLOAT:
        case DT_I1:
        case DT_I2:
        case DT_I4:
        case DT_I8:
        case DT_INT:
        case DT_NUMBER:
        case DT_R4:
        case DT_R8:
        case DT_TIME:
        case DT_TIME_TZ:
        case DT_UI1:
        case DT_UI2:
        case DT_UI4:
        case DT_UI8:
        case DT_URI:
        case DT_UUID:
            V_VT(typename) = VT_BSTR;
            V_BSTR(typename) = SysAllocString(dt_to_bstr(dt));

            if (!V_BSTR(typename))
                return E_OUTOFMEMORY;
            break;
        default:
            /* Other types (DTD equivalents) do not return anything here,
             * but the pointer part of the VARIANT is set to NULL */
            V_VT(typename) = VT_NULL;
            V_BSTR(typename) = NULL;
            break;
    }
    return (V_VT(typename) != VT_NULL) ? S_OK : S_FALSE;
}

static HRESULT WINAPI domelem_put_dataType(
    IXMLDOMElement *iface,
    BSTR dtName)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    HRESULT hr = E_FAIL;
    xmlChar *str;
    XDR_DT dt;

    TRACE("(%p)->(%s)\n", This, debugstr_w(dtName));

    if(dtName == NULL)
        return E_INVALIDARG;

    dt = bstr_to_dt(dtName, -1);

    /* An example of this is. The Text in the node needs to be a 0 or 1 for a boolean type.
       This applies to changing types (string->bool) or setting a new one
     */
    str = xmlNodeGetContent(get_element(This));
    hr = dt_validate(dt, str);
    xmlFree(str);

    /* Check all supported types. */
    if (hr == S_OK)
    {
        switch (dt)
        {
        case DT_BIN_BASE64:
        case DT_BIN_HEX:
        case DT_BOOLEAN:
        case DT_CHAR:
        case DT_DATE:
        case DT_DATE_TZ:
        case DT_DATETIME:
        case DT_DATETIME_TZ:
        case DT_FIXED_14_4:
        case DT_FLOAT:
        case DT_I1:
        case DT_I2:
        case DT_I4:
        case DT_I8:
        case DT_INT:
        case DT_NMTOKEN:
        case DT_NMTOKENS:
        case DT_NUMBER:
        case DT_R4:
        case DT_R8:
        case DT_STRING:
        case DT_TIME:
        case DT_TIME_TZ:
        case DT_UI1:
        case DT_UI2:
        case DT_UI4:
        case DT_UI8:
        case DT_URI:
        case DT_UUID:
            {
                xmlAttrPtr attr = xmlHasNsProp(get_element(This), DT_prefix, DT_nsURI);
                if (attr)
                {
                    attr = xmlSetNsProp(get_element(This), attr->ns, DT_prefix, dt_to_str(dt));
                    hr = S_OK;
                }
                else
                {
                    xmlNsPtr ns = xmlNewNs(get_element(This), DT_nsURI, DT_prefix);
                    if (ns)
                    {
                        attr = xmlNewNsProp(get_element(This), ns, DT_prefix, dt_to_str(dt));
                        if (attr)
                        {
                            xmlAddChild(get_element(This), (xmlNodePtr)attr);
                            hr = S_OK;
                        }
                        else
                            ERR("Failed to create Attribute\n");
                    }
                    else
                        ERR("Failed to create Namespace\n");
                }
            }
            break;
        default:
            FIXME("need to handle dt:%s\n", debugstr_dt(dt));
            break;
        }
    }

    return hr;
}

static HRESULT WINAPI domelem_get_xml(
    IXMLDOMElement *iface,
    BSTR* p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );

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

    return node_get_xml(&This->node, TRUE, p);
}

static HRESULT WINAPI domelem_transformNode(
    IXMLDOMElement *iface,
    IXMLDOMNode *node, BSTR *p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p %p)\n", This, node, p);
    return node_transform_node(&This->node, node, p);
}

static HRESULT WINAPI domelem_selectNodes(
    IXMLDOMElement *iface,
    BSTR p, IXMLDOMNodeList** outList)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList);
    return node_select_nodes(&This->node, p, outList);
}

static HRESULT WINAPI domelem_selectSingleNode(
    IXMLDOMElement *iface,
    BSTR p, IXMLDOMNode** outNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode);
    return node_select_singlenode(&This->node, p, outNode);
}

static HRESULT WINAPI domelem_get_parsed(
    IXMLDOMElement *iface,
    VARIANT_BOOL* isParsed)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("(%p)->(%p) stub!\n", This, isParsed);
    *isParsed = VARIANT_TRUE;
    return S_OK;
}

static HRESULT WINAPI domelem_get_namespaceURI(
    IXMLDOMElement *iface,
    BSTR* p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, p);
    return node_get_namespaceURI(&This->node, p);
}

static HRESULT WINAPI domelem_get_prefix(
    IXMLDOMElement *iface,
    BSTR* prefix)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, prefix);
    return node_get_prefix( &This->node, prefix );
}

static HRESULT WINAPI domelem_get_baseName(
    IXMLDOMElement *iface,
    BSTR* name)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    TRACE("(%p)->(%p)\n", This, name);
    return node_get_base_name( &This->node, name );
}

static HRESULT WINAPI domelem_transformNodeToObject(
    IXMLDOMElement *iface,
    IXMLDOMNode* domNode, VARIANT var1)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
    return E_NOTIMPL;
}

static HRESULT WINAPI domelem_get_tagName(
    IXMLDOMElement *iface,
    BSTR* p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    xmlNodePtr element;
    const xmlChar *prefix;
    xmlChar *qname;

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

    if (!p) return E_INVALIDARG;

    element = get_element( This );
    if ( !element )
        return E_FAIL;

    prefix = element->ns ? element->ns->prefix : NULL;
    qname = xmlBuildQName(element->name, prefix, NULL, 0);

    *p = bstr_from_xmlChar(qname);
    if (qname != element->name) xmlFree(qname);

    return *p ? S_OK : E_OUTOFMEMORY;
}

static HRESULT WINAPI domelem_getAttribute(
    IXMLDOMElement *iface,
    BSTR name, VARIANT* value)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    xmlNodePtr element;
    xmlChar *xml_name, *xml_value = NULL;
    HRESULT hr = S_FALSE;

    TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value);

    if(!value || !name)
        return E_INVALIDARG;

    element = get_element( This );
    if ( !element )
        return E_FAIL;

    V_BSTR(value) = NULL;
    V_VT(value) = VT_NULL;

    xml_name = xmlchar_from_wchar( name );

    if(!xmlValidateNameValue(xml_name))
        hr = E_FAIL;
    else
        xml_value = xmlGetNsProp(element, xml_name, NULL);

    heap_free(xml_name);
    if(xml_value)
    {
        V_VT(value) = VT_BSTR;
        V_BSTR(value) = bstr_from_xmlChar( xml_value );
        xmlFree(xml_value);
        hr = S_OK;
    }

    return hr;
}

static HRESULT WINAPI domelem_setAttribute(
    IXMLDOMElement *iface,
    BSTR name, VARIANT value)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    xmlChar *xml_name, *xml_value, *local, *prefix;
    xmlNodePtr element;
    HRESULT hr = S_OK;

    TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_variant(&value));

    element = get_element( This );
    if ( !element )
        return E_FAIL;

    if (V_VT(&value) != VT_BSTR)
    {
        VARIANT var;

        VariantInit(&var);
        hr = VariantChangeType(&var, &value, 0, VT_BSTR);
        if (hr != S_OK)
        {
            FIXME("VariantChangeType failed\n");
            return hr;
        }

        xml_value = xmlchar_from_wchar(V_BSTR(&var));
        VariantClear(&var);
    }
    else
        xml_value = xmlchar_from_wchar(V_BSTR(&value));

    xml_name = xmlchar_from_wchar( name );

    if ((local = xmlSplitQName2(xml_name, &prefix)))
    {
        static const xmlChar* xmlnsA = (const xmlChar*)"xmlns";
        xmlNsPtr ns = NULL;

        /* it's not allowed to modify existing namespace definition */
        if (xmlStrEqual(prefix, xmlnsA))
            ns = xmlSearchNs(element->doc, element, local);

        xmlFree(prefix);
        xmlFree(local);

        if (ns)
        {
            int cmp = xmlStrEqual(ns->href, xml_value);
            heap_free(xml_value);
            heap_free(xml_name);
            return cmp ? S_OK : E_INVALIDARG;
        }
    }

    if (!xmlSetNsProp(element, NULL, xml_name, xml_value))
        hr = E_FAIL;

    heap_free(xml_value);
    heap_free(xml_name);

    return hr;
}

static HRESULT WINAPI domelem_removeAttribute(
    IXMLDOMElement *iface,
    BSTR p)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    IXMLDOMNamedNodeMap *attr;
    HRESULT hr;

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

    hr = IXMLDOMElement_get_attributes(iface, &attr);
    if (hr != S_OK) return hr;

    hr = IXMLDOMNamedNodeMap_removeNamedItem(attr, p, NULL);
    IXMLDOMNamedNodeMap_Release(attr);

    return hr;
}

static HRESULT WINAPI domelem_getAttributeNode(
    IXMLDOMElement *iface,
    BSTR p, IXMLDOMAttribute** attributeNode )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    xmlChar *local, *prefix, *nameA;
    HRESULT hr = S_FALSE;
    xmlNodePtr element;
    xmlAttrPtr attr;

    TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode);

    element = get_element( This );
    if (!element) return E_FAIL;

    if (attributeNode) *attributeNode = NULL;

    nameA = xmlchar_from_wchar(p);
    if (!xmlValidateNameValue(nameA))
    {
        heap_free(nameA);
        return E_FAIL;
    }

    if (!attributeNode)
    {
        heap_free(nameA);
        return S_FALSE;
    }

    *attributeNode = NULL;

    local = xmlSplitQName2(nameA, &prefix);

    if (local)
    {
        /* try to get namespace for supplied qualified name */
        xmlNsPtr ns = xmlSearchNs(element->doc, element, prefix);
        xmlFree(prefix);

        attr = xmlHasNsProp(element, local, ns ? ns->href : NULL);
        xmlFree(local);
    }
    else
    {
        attr = xmlHasProp(element, nameA);
        /* attribute has attached namespace and we requested non-qualified
           name - it's a failure case */
        if (attr && attr->ns) attr = NULL;
    }

    heap_free(nameA);

    if (attr)
    {
        IUnknown *unk = create_attribute((xmlNodePtr)attr);
        hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode);
        IUnknown_Release(unk);
    }

    return hr;
}

static HRESULT WINAPI domelem_setAttributeNode(
    IXMLDOMElement *iface,
    IXMLDOMAttribute* attribute,
    IXMLDOMAttribute** old)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
    xmlChar *name, *value;
    BSTR nameW, prefix;
    xmlnode *attr_node;
    xmlAttrPtr attr;
    VARIANT valueW;
    HRESULT hr;

    FIXME("(%p)->(%p %p): semi-stub\n", This, attribute, old);

    if (!attribute) return E_INVALIDARG;

    attr_node = get_node_obj((IXMLDOMNode*)attribute);
    if (!attr_node) return E_FAIL;

    if (attr_node->parent)
    {
        WARN("attempt to add already used attribute\n");
        return E_FAIL;
    }

    hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW);
    if (hr != S_OK) return hr;

    /* adding xmlns attribute doesn't change a tree or existing namespace definition */
    if (!strcmpW(nameW, xmlnsW))
    {
        SysFreeString(nameW);
        return DISP_E_UNKNOWNNAME;
    }

    hr = IXMLDOMAttribute_get_nodeValue(attribute, &valueW);
    if (hr != S_OK)
    {
        SysFreeString(nameW);
        return hr;
    }

    if (old) *old = NULL;

    TRACE("attribute: %s=%s\n", debugstr_w(nameW), debugstr_w(V_BSTR(&valueW)));

    hr = IXMLDOMAttribute_get_prefix(attribute, &prefix);
    if (hr == S_OK)
    {
        FIXME("namespaces not supported: %s\n", debugstr_w(prefix));
        SysFreeString(prefix);
    }

    name = xmlchar_from_wchar(nameW);
    value = xmlchar_from_wchar(V_BSTR(&valueW));

    if (!name || !value)
    {
        SysFreeString(nameW);
        VariantClear(&valueW);
        heap_free(name);
        heap_free(value);
        return E_OUTOFMEMORY;
    }

    attr = xmlSetNsProp(get_element(This), NULL, name, value);
    if (attr)
        attr_node->parent = (IXMLDOMNode*)iface;

    SysFreeString(nameW);
    VariantClear(&valueW);
    heap_free(name);
    heap_free(value);

    return attr ? S_OK : E_FAIL;
}

static HRESULT WINAPI domelem_removeAttributeNode(
    IXMLDOMElement *iface,
    IXMLDOMAttribute* domAttribute,
    IXMLDOMAttribute** attributeNode)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("(%p)->(%p %p)\n", This, domAttribute, attributeNode);
    return E_NOTIMPL;
}

static HRESULT WINAPI domelem_getElementsByTagName(
    IXMLDOMElement *iface,
    BSTR tagName, IXMLDOMNodeList** resultList)
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    xmlChar *query;
    HRESULT hr;
    BOOL XPath;

    TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);

    if (!tagName || !resultList) return E_INVALIDARG;

    XPath = is_xpathmode(get_element(This)->doc);
    set_xpathmode(get_element(This)->doc, TRUE);
    query = tagName_to_XPath(tagName);
    hr = create_selection(get_element(This), query, resultList);
    xmlFree(query);
    set_xpathmode(get_element(This)->doc, XPath);

    return hr;
}

static HRESULT WINAPI domelem_normalize(
    IXMLDOMElement *iface )
{
    domelem *This = impl_from_IXMLDOMElement( iface );
    FIXME("%p\n", This);
    return E_NOTIMPL;
}

static const struct IXMLDOMElementVtbl domelem_vtbl =
{
    domelem_QueryInterface,
    domelem_AddRef,
    domelem_Release,
    domelem_GetTypeInfoCount,
    domelem_GetTypeInfo,
    domelem_GetIDsOfNames,
    domelem_Invoke,
    domelem_get_nodeName,
    domelem_get_nodeValue,
    domelem_put_nodeValue,
    domelem_get_nodeType,
    domelem_get_parentNode,
    domelem_get_childNodes,
    domelem_get_firstChild,
    domelem_get_lastChild,
    domelem_get_previousSibling,
    domelem_get_nextSibling,
    domelem_get_attributes,
    domelem_insertBefore,
    domelem_replaceChild,
    domelem_removeChild,
    domelem_appendChild,
    domelem_hasChildNodes,
    domelem_get_ownerDocument,
    domelem_cloneNode,
    domelem_get_nodeTypeString,
    domelem_get_text,
    domelem_put_text,
    domelem_get_specified,
    domelem_get_definition,
    domelem_get_nodeTypedValue,
    domelem_put_nodeTypedValue,
    domelem_get_dataType,
    domelem_put_dataType,
    domelem_get_xml,
    domelem_transformNode,
    domelem_selectNodes,
    domelem_selectSingleNode,
    domelem_get_parsed,
    domelem_get_namespaceURI,
    domelem_get_prefix,
    domelem_get_baseName,
    domelem_transformNodeToObject,
    domelem_get_tagName,
    domelem_getAttribute,
    domelem_setAttribute,
    domelem_removeAttribute,
    domelem_getAttributeNode,
    domelem_setAttributeNode,
    domelem_removeAttributeNode,
    domelem_getElementsByTagName,
    domelem_normalize,
};

static HRESULT domelem_get_qualified_item(const xmlNodePtr node, BSTR name, BSTR uri,
    IXMLDOMNode **item)
{
    xmlAttrPtr attr;
    xmlChar *nameA;
    xmlChar *href;

    TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item);

    if (!name || !item) return E_INVALIDARG;

    if (uri && *uri)
    {
        href = xmlchar_from_wchar(uri);
        if (!href) return E_OUTOFMEMORY;
    }
    else
        href = NULL;

    nameA = xmlchar_from_wchar(name);
    if (!nameA)
    {
        heap_free(href);
        return E_OUTOFMEMORY;
    }

    attr = xmlHasNsProp(node, nameA, href);

    heap_free(nameA);
    heap_free(href);

    if (!attr)
    {
        *item = NULL;
        return S_FALSE;
    }

    *item = create_node((xmlNodePtr)attr);

    return S_OK;
}

static HRESULT domelem_get_named_item(const xmlNodePtr node, BSTR name, IXMLDOMNode **item)
{
    xmlChar *nameA, *local, *prefix;
    BSTR uriW, localW;
    xmlNsPtr ns;
    HRESULT hr;

    TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item );

    nameA = xmlchar_from_wchar(name);
    local = xmlSplitQName2(nameA, &prefix);
    heap_free(nameA);

    if (!local)
        return domelem_get_qualified_item(node, name, NULL, item);

    /* try to get namespace uri for supplied qualified name */
    ns = xmlSearchNs(node->doc, node, prefix);

    xmlFree(prefix);

    if (!ns)
    {
        xmlFree(local);
        if (item) *item = NULL;
        return item ? S_FALSE : E_INVALIDARG;
    }

    uriW = bstr_from_xmlChar(ns->href);
    localW = bstr_from_xmlChar(local);
    xmlFree(local);

    TRACE("got qualified node %s, uri=%s\n", debugstr_w(localW), debugstr_w(uriW));

    hr = domelem_get_qualified_item(node, localW, uriW, item);

    SysFreeString(localW);
    SysFreeString(uriW);

    return hr;
}

static HRESULT domelem_set_named_item(xmlNodePtr node, IXMLDOMNode *newItem, IXMLDOMNode **namedItem)
{
    xmlNodePtr nodeNew;
    xmlnode *ThisNew;

    TRACE("(%p)->(%p %p)\n", node, newItem, namedItem );

    if(!newItem)
        return E_INVALIDARG;

    if(namedItem) *namedItem = NULL;

    /* Must be an Attribute */
    ThisNew = get_node_obj( newItem );
    if(!ThisNew) return E_FAIL;

    if(ThisNew->node->type != XML_ATTRIBUTE_NODE)
        return E_FAIL;

    if(!ThisNew->node->parent)
        if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
            WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);

    nodeNew = xmlAddChild(node, ThisNew->node);

    if(namedItem)
        *namedItem = create_node( nodeNew );
    return S_OK;
}

static HRESULT domelem_remove_qualified_item(xmlNodePtr node, BSTR name, BSTR uri, IXMLDOMNode **item)
{
    xmlChar *nameA, *href;
    xmlAttrPtr attr;

    TRACE("(%p)->(%s %s %p)\n", node, debugstr_w(name), debugstr_w(uri), item);

    if (!name) return E_INVALIDARG;

    if (uri && *uri)
    {
        href = xmlchar_from_wchar(uri);
        if (!href) return E_OUTOFMEMORY;
    }
    else
        href = NULL;

    nameA = xmlchar_from_wchar(name);
    if (!nameA)
    {
        heap_free(href);
        return E_OUTOFMEMORY;
    }

    attr = xmlHasNsProp(node, nameA, href);

    heap_free(nameA);
    heap_free(href);

    if (!attr)
    {
        if (item) *item = NULL;
        return S_FALSE;
    }

    if (item)
    {
        xmlUnlinkNode( (xmlNodePtr) attr );
        xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr );
        *item = create_node( (xmlNodePtr) attr );
    }
    else
    {
        if (xmlRemoveProp(attr) == -1)
            ERR("xmlRemoveProp failed\n");
    }

    return S_OK;
}

static HRESULT domelem_remove_named_item(xmlNodePtr node, BSTR name, IXMLDOMNode **item)
{
    TRACE("(%p)->(%s %p)\n", node, debugstr_w(name), item);
    return domelem_remove_qualified_item(node, name, NULL, item);
}

static HRESULT domelem_get_item(const xmlNodePtr node, LONG index, IXMLDOMNode **item)
{
    xmlAttrPtr curr;
    LONG attrIndex;

    TRACE("(%p)->(%d %p)\n", node, index, item);

    *item = NULL;

    if (index < 0)
        return S_FALSE;

    curr = node->properties;

    for (attrIndex = 0; attrIndex < index; attrIndex++) {
        if (curr->next == NULL)
            return S_FALSE;
        else
            curr = curr->next;
    }

    *item = create_node( (xmlNodePtr) curr );

    return S_OK;
}

static HRESULT domelem_get_length(const xmlNodePtr node, LONG *length)
{
    xmlAttrPtr first;
    xmlAttrPtr curr;
    LONG attrCount;

    TRACE("(%p)->(%p)\n", node, length);

    if( !length )
        return E_INVALIDARG;

    first = node->properties;
    if (first == NULL) {
	*length = 0;
	return S_OK;
    }

    curr = first;
    attrCount = 1;
    while (curr->next) {
        attrCount++;
        curr = curr->next;
    }
    *length = attrCount;

    return S_OK;
}

static HRESULT domelem_next_node(const xmlNodePtr node, LONG *iter, IXMLDOMNode **nextNode)
{
    xmlAttrPtr curr;
    LONG i;

    TRACE("(%p)->(%d: %p)\n", node, *iter, nextNode);

    *nextNode = NULL;

    curr = node->properties;

    for (i = 0; i < *iter; i++) {
        if (curr->next == NULL)
            return S_FALSE;
        else
            curr = curr->next;
    }

    (*iter)++;
    *nextNode = create_node((xmlNodePtr)curr);

    return S_OK;
}

static const struct nodemap_funcs domelem_attr_map = {
    domelem_get_named_item,
    domelem_set_named_item,
    domelem_remove_named_item,
    domelem_get_item,
    domelem_get_length,
    domelem_get_qualified_item,
    domelem_remove_qualified_item,
    domelem_next_node
};

static const tid_t domelem_iface_tids[] = {
    IXMLDOMElement_tid,
    0
};

static dispex_static_data_t domelem_dispex = {
    NULL,
    IXMLDOMElement_tid,
    NULL,
    domelem_iface_tids
};

IUnknown* create_element( xmlNodePtr element )
{
    domelem *This;

    This = heap_alloc( sizeof *This );
    if ( !This )
        return NULL;

    This->IXMLDOMElement_iface.lpVtbl = &domelem_vtbl;
    This->ref = 1;

    init_xmlnode(&This->node, element, (IXMLDOMNode*)&This->IXMLDOMElement_iface, &domelem_dispex);

    return (IUnknown*)&This->IXMLDOMElement_iface;
}

#endif
