/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qdeclarativexmlhttprequest_p.h"

#include "qdeclarativeengine.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativerefcount_p.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativeexpression_p.h"
#include "qdeclarativeglobal_p.h"

#include <QtCore/qobject.h>
#include <QtScript/qscriptvalue.h>
#include <QtScript/qscriptcontext.h>
#include <QtScript/qscriptengine.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtCore/qtextcodec.h>
#include <QtCore/qxmlstream.h>
#include <QtCore/qstack.h>
#include <QtCore/qdebug.h>

#ifndef QT_NO_XMLSTREAMREADER

// From DOM-Level-3-Core spec
// http://www.w3.org/TR/DOM-Level-3-Core/core.html
#define INDEX_SIZE_ERR 1
#define DOMSTRING_SIZE_ERR 2
#define HIERARCHY_REQUEST_ERR 3
#define WRONG_DOCUMENT_ERR 4
#define INVALID_CHARACTER_ERR 5
#define NO_DATA_ALLOWED_ERR 6
#define NO_MODIFICATION_ALLOWED_ERR 7
#define NOT_FOUND_ERR 8
#define NOT_SUPPORTED_ERR 9
#define INUSE_ATTRIBUTE_ERR 10
#define INVALID_STATE_ERR 11
#define SYNTAX_ERR 12
#define INVALID_MODIFICATION_ERR 13
#define NAMESPACE_ERR 14
#define INVALID_ACCESS_ERR 15
#define VALIDATION_ERR 16
#define TYPE_MISMATCH_ERR 17

#define THROW_DOM(error, desc) \
{ \
    QScriptValue errorValue = context->throwError(QLatin1String(desc)); \
    errorValue.setProperty(QLatin1String("code"), error); \
    return errorValue; \
} 

#define THROW_SYNTAX(desc) \
    return context->throwError(QScriptContext::SyntaxError, QLatin1String(desc));
#define THROW_REFERENCE(desc) \
    return context->throwError(QScriptContext::ReferenceError, QLatin1String(desc));

#define D(arg) (arg)->release()
#define A(arg) (arg)->addref()

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(xhrDump, QML_XHR_DUMP);

class DocumentImpl;
class NodeImpl 
{
public:
    NodeImpl() : type(Element), document(0), parent(0) {}
    virtual ~NodeImpl() { 
        for (int ii = 0; ii < children.count(); ++ii)
            delete children.at(ii);
        for (int ii = 0; ii < attributes.count(); ++ii)
            delete attributes.at(ii);
    }

    // These numbers are copied from the Node IDL definition
    enum Type { 
        Attr = 2, 
        CDATA = 4, 
        Comment = 8, 
        Document = 9, 
        DocumentFragment = 11, 
        DocumentType = 10,
        Element = 1, 
        Entity = 6, 
        EntityReference = 5,
        Notation = 12, 
        ProcessingInstruction = 7, 
        Text = 3
    };
    Type type;

    QString namespaceUri;
    QString name;

    QString data;

    void addref();
    void release();

    DocumentImpl *document;
    NodeImpl *parent;

    QList<NodeImpl *> children;
    QList<NodeImpl *> attributes;
};

class DocumentImpl : public QDeclarativeRefCount, public NodeImpl
{
public:
    DocumentImpl() : root(0) { type = Document; }
    virtual ~DocumentImpl() {
        if (root) delete root;
    }

    QString version;
    QString encoding;
    bool isStandalone;

    NodeImpl *root;

    void addref() { QDeclarativeRefCount::addref(); }
    void release() { QDeclarativeRefCount::release(); }
};

class NamedNodeMap
{
public:
    // JS API
    static QScriptValue length(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
    static QScriptValue create(QScriptEngine *, NodeImpl *, QList<NodeImpl *> *);

    NamedNodeMap();
    NamedNodeMap(const NamedNodeMap &);
    ~NamedNodeMap();
    bool isNull();

    NodeImpl *d;
    QList<NodeImpl *> *list;
private:
    NamedNodeMap &operator=(const NamedNodeMap &);
};

class NamedNodeMapClass : public QScriptClass
{
public:
    NamedNodeMapClass(QScriptEngine *engine) : QScriptClass(engine) {}

    virtual QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id);
    virtual QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
};

class NodeList 
{
public:
    // JS API
    static QScriptValue length(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
    static QScriptValue create(QScriptEngine *, NodeImpl *);

    NodeList();
    NodeList(const NodeList &);
    ~NodeList();
    bool isNull();

    NodeImpl *d;
private:
    NodeList &operator=(const NodeList &);
};

class NodeListClass : public QScriptClass
{
public:
    NodeListClass(QScriptEngine *engine) : QScriptClass(engine) {}
    virtual QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id);
    virtual QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id);
};

class Node
{
public:
    // JS API
    static QScriptValue nodeName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue nodeValue(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue nodeType(QScriptContext *context, QScriptEngine *engine);

    static QScriptValue parentNode(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue childNodes(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue firstChild(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue lastChild(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue previousSibling(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue nextSibling(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue attributes(QScriptContext *context, QScriptEngine *engine);

    //static QScriptValue ownerDocument(QScriptContext *context, QScriptEngine *engine);
    //static QScriptValue namespaceURI(QScriptContext *context, QScriptEngine *engine);
    //static QScriptValue prefix(QScriptContext *context, QScriptEngine *engine);
    //static QScriptValue localName(QScriptContext *context, QScriptEngine *engine);
    //static QScriptValue baseURI(QScriptContext *context, QScriptEngine *engine);
    //static QScriptValue textContent(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
    static QScriptValue create(QScriptEngine *, NodeImpl *);

    Node();
    Node(const Node &o);
    ~Node();
    bool isNull() const;

    NodeImpl *d;

private:
    Node &operator=(const Node &);
};

class Element : public Node
{
public:
    // C++ API
    static QScriptValue prototype(QScriptEngine *);
};

class Attr : public Node
{
public:
    // JS API
    static QScriptValue name(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue specified(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue value(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue ownerElement(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue schemaTypeInfo(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue isId(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
};

class CharacterData : public Node
{
public:
    // JS API
    static QScriptValue length(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
};

class Text : public CharacterData
{
public:
    // JS API
    static QScriptValue isElementContentWhitespace(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue wholeText(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
};

class CDATA : public Text
{
public:
    // C++ API
    static QScriptValue prototype(QScriptEngine *);
};

class Document : public Node
{
public:
    // JS API
    static QScriptValue xmlVersion(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue xmlEncoding(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue xmlStandalone(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue documentElement(QScriptContext *context, QScriptEngine *engine);

    // C++ API
    static QScriptValue prototype(QScriptEngine *);
    static QScriptValue load(QScriptEngine *engine, const QByteArray &data);
};

QT_END_NAMESPACE

Q_DECLARE_METATYPE(Node)
Q_DECLARE_METATYPE(NodeList)
Q_DECLARE_METATYPE(NamedNodeMap)

QT_BEGIN_NAMESPACE

void NodeImpl::addref() 
{
    A(document);
}

void NodeImpl::release()
{
    D(document);
}

QScriptValue Node::nodeName(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    switch (node.d->type) {
    case NodeImpl::Document:
        return QScriptValue(QLatin1String("#document"));
    case NodeImpl::CDATA:
        return QScriptValue(QLatin1String("#cdata-section"));
    case NodeImpl::Text:
        return QScriptValue(QLatin1String("#text"));
    default:
        return QScriptValue(node.d->name);
    }
}

QScriptValue Node::nodeValue(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (node.d->type == NodeImpl::Document ||
        node.d->type == NodeImpl::DocumentFragment ||
        node.d->type == NodeImpl::DocumentType ||
        node.d->type == NodeImpl::Element ||
        node.d->type == NodeImpl::Entity ||
        node.d->type == NodeImpl::EntityReference ||
        node.d->type == NodeImpl::Notation)
        return engine->nullValue();

    return QScriptValue(node.d->data);
}

QScriptValue Node::nodeType(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();
    return QScriptValue(node.d->type);
}

QScriptValue Node::parentNode(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (node.d->parent) return Node::create(engine, node.d->parent);
    else return engine->nullValue();
}

QScriptValue Node::childNodes(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return NodeList::create(engine, node.d);
}

QScriptValue Node::firstChild(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (node.d->children.isEmpty()) return engine->nullValue();
    else return Node::create(engine, node.d->children.first());
}

QScriptValue Node::lastChild(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (node.d->children.isEmpty()) return engine->nullValue();
    else return Node::create(engine, node.d->children.last());
}

QScriptValue Node::previousSibling(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (!node.d->parent) return engine->nullValue();

    for (int ii = 0; ii < node.d->parent->children.count(); ++ii) {
        if (node.d->parent->children.at(ii) == node.d) {
            if (ii == 0) return engine->nullValue();
            else return Node::create(engine, node.d->parent->children.at(ii - 1));
        }
    }

    return engine->nullValue();
}

QScriptValue Node::nextSibling(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (!node.d->parent) return engine->nullValue();

    for (int ii = 0; ii < node.d->parent->children.count(); ++ii) {
        if (node.d->parent->children.at(ii) == node.d) {
            if ((ii + 1) == node.d->parent->children.count()) return engine->nullValue();
            else return Node::create(engine, node.d->parent->children.at(ii + 1)); 
        }
    }

    return engine->nullValue();
}

QScriptValue Node::attributes(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    if (node.d->type != NodeImpl::Element)
        return engine->nullValue();
    else
        return NamedNodeMap::create(engine, node.d, &node.d->attributes);
}

QScriptValue Node::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();

    proto.setProperty(QLatin1String("nodeName"), engine->newFunction(nodeName), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("nodeValue"), engine->newFunction(nodeValue), QScriptValue::ReadOnly | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
    proto.setProperty(QLatin1String("nodeType"), engine->newFunction(nodeType), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("parentNode"), engine->newFunction(parentNode), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("childNodes"), engine->newFunction(childNodes), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("firstChild"), engine->newFunction(firstChild), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("lastChild"), engine->newFunction(lastChild), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("previousSibling"), engine->newFunction(previousSibling), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("nextSibling"), engine->newFunction(nextSibling), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("attributes"), engine->newFunction(attributes), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue Node::create(QScriptEngine *engine, NodeImpl *data)
{
    QScriptValue instance = engine->newObject();

    switch (data->type) {
    case NodeImpl::Attr:
        instance.setPrototype(Attr::prototype(engine));
        break;
    case NodeImpl::Comment:
    case NodeImpl::Document:
    case NodeImpl::DocumentFragment:
    case NodeImpl::DocumentType:
    case NodeImpl::Entity:
    case NodeImpl::EntityReference:
    case NodeImpl::Notation:
    case NodeImpl::ProcessingInstruction:
        return QScriptValue();
    case NodeImpl::CDATA:
        instance.setPrototype(CDATA::prototype(engine));
        break;
    case NodeImpl::Text:
        instance.setPrototype(Text::prototype(engine));
        break;
    case NodeImpl::Element:
        instance.setPrototype(Element::prototype(engine));
        break;
    }

    Node node;
    node.d = data;
    if (data) A(data);

    return engine->newVariant(instance, qVariantFromValue(node));
}

QScriptValue Element::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(Node::prototype(engine));

    proto.setProperty(QLatin1String("tagName"), engine->newFunction(nodeName), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue Attr::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(Node::prototype(engine));

    proto.setProperty(QLatin1String("name"), engine->newFunction(name), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("value"), engine->newFunction(value), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("ownerElement"), engine->newFunction(ownerElement), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue Attr::name(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return QScriptValue(node.d->name);
}

QScriptValue Attr::value(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return QScriptValue(node.d->data);
}

QScriptValue Attr::ownerElement(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return Node::create(engine, node.d->parent);
}

QScriptValue CharacterData::length(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return QScriptValue(node.d->data.length());
}

QScriptValue CharacterData::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(Node::prototype(engine));

    proto.setProperty(QLatin1String("data"), engine->newFunction(nodeValue), QScriptValue::ReadOnly | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
    proto.setProperty(QLatin1String("length"), engine->newFunction(length), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue Text::isElementContentWhitespace(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return node.d->data.trimmed().isEmpty();
}

QScriptValue Text::wholeText(QScriptContext *context, QScriptEngine *engine)
{
    Node node = qscriptvalue_cast<Node>(context->thisObject());
    if (node.isNull()) return engine->undefinedValue();

    return node.d->data;
}

QScriptValue Text::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(CharacterData::prototype(engine));

    proto.setProperty(QLatin1String("isElementContentWhitespace"), engine->newFunction(isElementContentWhitespace), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    proto.setProperty(QLatin1String("wholeText"), engine->newFunction(wholeText), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue CDATA::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(Text::prototype(engine));
    return proto;
}

QScriptValue Document::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();
    proto.setPrototype(Node::prototype(engine));

    proto.setProperty(QLatin1String("xmlVersion"), engine->newFunction(xmlVersion), QScriptValue::ReadOnly | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
    proto.setProperty(QLatin1String("xmlEncoding"), engine->newFunction(xmlEncoding), QScriptValue::ReadOnly | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
    proto.setProperty(QLatin1String("xmlStandalone"), engine->newFunction(xmlStandalone), QScriptValue::ReadOnly | QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
    proto.setProperty(QLatin1String("documentElement"), engine->newFunction(documentElement), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue Document::load(QScriptEngine *engine, const QByteArray &data)
{
    Q_ASSERT(engine);

    DocumentImpl *document = 0;
    QStack<NodeImpl *> nodeStack;

    QXmlStreamReader reader(data);

    while (!reader.atEnd()) {
        switch (reader.readNext()) {
        case QXmlStreamReader::NoToken:
            break;
        case QXmlStreamReader::Invalid:
            break;
        case QXmlStreamReader::StartDocument:
            Q_ASSERT(!document);
            document = new DocumentImpl;
            document->document = document;
            document->version = reader.documentVersion().toString();
            document->encoding = reader.documentEncoding().toString();
            document->isStandalone = reader.isStandaloneDocument();
            break;
        case QXmlStreamReader::EndDocument:
            break;
        case QXmlStreamReader::StartElement: 
        {
            Q_ASSERT(document);
            NodeImpl *node = new NodeImpl;
            node->document = document;
            node->namespaceUri = reader.namespaceUri().toString();
            node->name = reader.name().toString();
            if (nodeStack.isEmpty()) {
                document->root = node;
            } else {
                node->parent = nodeStack.top();
                node->parent->children.append(node);
            }
            nodeStack.append(node);

            foreach (const QXmlStreamAttribute &a, reader.attributes()) {
                NodeImpl *attr = new NodeImpl;
                attr->document = document;
                attr->type = NodeImpl::Attr;
                attr->namespaceUri = a.namespaceUri().toString();
                attr->name = a.name().toString();
                attr->data = a.value().toString();
                attr->parent = node;
                node->attributes.append(attr);
            }
        } 
            break;
        case QXmlStreamReader::EndElement:
            nodeStack.pop();
            break;
        case QXmlStreamReader::Characters:
        {
            NodeImpl *node = new NodeImpl;
            node->document = document;
            node->type = reader.isCDATA()?NodeImpl::CDATA:NodeImpl::Text;
            node->parent = nodeStack.top();
            node->parent->children.append(node);
            node->data = reader.text().toString();
        }
            break;
        case QXmlStreamReader::Comment:
            break;
        case QXmlStreamReader::DTD:
            break;
        case QXmlStreamReader::EntityReference:
            break;
        case QXmlStreamReader::ProcessingInstruction:
            break;
        }
    }

    if (!document || reader.hasError()) {
        if (document) D(document);
        return engine->nullValue();
    }

    QScriptValue instance = engine->newObject();
    instance.setPrototype(Document::prototype(engine));
    Node documentNode;
    documentNode.d = document;
    return engine->newVariant(instance, qVariantFromValue(documentNode));
}

Node::Node()
: d(0)
{
}

Node::Node(const Node &o)
: d(o.d)
{
    if (d) A(d);
}

Node::~Node()
{
    if (d) D(d);
}

bool Node::isNull() const
{
    return d == 0;
}

QScriptValue NamedNodeMap::length(QScriptContext *context, QScriptEngine *engine)
{
    NamedNodeMap map = qscriptvalue_cast<NamedNodeMap>(context->thisObject().data());
    if (map.isNull()) return engine->undefinedValue();

    return QScriptValue(map.list->count());
}

QScriptValue NamedNodeMap::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();

    proto.setProperty(QLatin1String("length"), engine->newFunction(length), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue NamedNodeMap::create(QScriptEngine *engine, NodeImpl *data, QList<NodeImpl *> *list)
{
    QScriptValue instance = engine->newObject();
    instance.setPrototype(NamedNodeMap::prototype(engine));

    NamedNodeMap map;
    map.d = data;
    map.list = list;
    if (data) A(data);

    instance.setData(engine->newVariant(qVariantFromValue(map)));

    if (!QDeclarativeScriptEngine::get(engine)->namedNodeMapClass)
        QDeclarativeScriptEngine::get(engine)->namedNodeMapClass= new NamedNodeMapClass(engine);

    instance.setScriptClass(QDeclarativeScriptEngine::get(engine)->namedNodeMapClass);

    return instance;
}

NamedNodeMap::NamedNodeMap()
: d(0), list(0)
{
}

NamedNodeMap::NamedNodeMap(const NamedNodeMap &o)
: d(o.d), list(o.list)
{
    if (d) A(d);
}

NamedNodeMap::~NamedNodeMap()
{
    if (d) D(d);
}

bool NamedNodeMap::isNull()
{
    return d == 0;
}

QScriptValue NodeList::length(QScriptContext *context, QScriptEngine *engine)
{
    NodeList list = qscriptvalue_cast<NodeList>(context->thisObject().data());
    if (list.isNull()) return engine->undefinedValue();

    return QScriptValue(list.d->children.count());
}

QScriptValue NodeList::prototype(QScriptEngine *engine)
{
    QScriptValue proto = engine->newObject();

    proto.setProperty(QLatin1String("length"), engine->newFunction(length), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);

    return proto;
}

QScriptValue NodeList::create(QScriptEngine *engine, NodeImpl *data)
{
    QScriptValue instance = engine->newObject();
    instance.setPrototype(NodeList::prototype(engine));

    NodeList list;
    list.d = data;
    if (data) A(data);

    instance.setData(engine->newVariant(qVariantFromValue(list)));

    if (!QDeclarativeScriptEngine::get(engine)->nodeListClass)
        QDeclarativeScriptEngine::get(engine)->nodeListClass= new NodeListClass(engine);

    instance.setScriptClass(QDeclarativeScriptEngine::get(engine)->nodeListClass);

    return instance;
}

NodeList::NodeList()
: d(0)
{
}

NodeList::NodeList(const NodeList &o)
: d(o.d)
{
    if (d) A(d);
}

NodeList::~NodeList()
{
    if (d) D(d);
}

bool NodeList::isNull()
{
    return d == 0;
}

NamedNodeMapClass::QueryFlags NamedNodeMapClass::queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id)
{
    if (!(flags & HandlesReadAccess))
        return 0;

    NamedNodeMap map = qscriptvalue_cast<NamedNodeMap>(object.data());
    Q_ASSERT(!map.isNull());

    bool ok = false;
    QString nameString = name.toString();
    uint index = nameString.toUInt(&ok);
    if (ok) {
        if ((uint)map.list->count() <= index)
            return 0;

        *id = index;
        return HandlesReadAccess;
    } else {
        for (int ii = 0; ii < map.list->count(); ++ii) {
            if (map.list->at(ii) && map.list->at(ii)->name == nameString) {
                *id = ii;
                return HandlesReadAccess;
            }
        }
    }

    return 0;
}

QScriptValue NamedNodeMapClass::property(const QScriptValue &object, const QScriptString &, uint id)
{
    NamedNodeMap map = qscriptvalue_cast<NamedNodeMap>(object.data());
    return Node::create(engine(), map.list->at(id));
}

NodeListClass::QueryFlags NodeListClass::queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id)
{
    if (!(flags & HandlesReadAccess))
        return 0;

    bool ok = false;
    uint index = name.toString().toUInt(&ok);
    if (!ok)
        return 0;

    NodeList list = qscriptvalue_cast<NodeList>(object.data());
    if (list.isNull() || (uint)list.d->children.count() <= index)
        return 0; // ### I think we're meant to raise an exception

    *id = index;
    return HandlesReadAccess;
}

QScriptValue NodeListClass::property(const QScriptValue &object, const QScriptString &, uint id)
{
    NodeList list = qscriptvalue_cast<NodeList>(object.data());
    return Node::create(engine(), list.d->children.at(id));
}

QScriptValue Document::documentElement(QScriptContext *context, QScriptEngine *engine)
{
    Node document = qscriptvalue_cast<Node>(context->thisObject());
    if (document.isNull() || document.d->type != NodeImpl::Document) return engine->undefinedValue();

    return Node::create(engine, static_cast<DocumentImpl *>(document.d)->root);
}

QScriptValue Document::xmlStandalone(QScriptContext *context, QScriptEngine *engine)
{
    Node document = qscriptvalue_cast<Node>(context->thisObject());
    if (document.isNull() || document.d->type != NodeImpl::Document) return engine->undefinedValue();

    return QScriptValue(static_cast<DocumentImpl *>(document.d)->isStandalone);
}

QScriptValue Document::xmlVersion(QScriptContext *context, QScriptEngine *engine)
{
    Node document = qscriptvalue_cast<Node>(context->thisObject());
    if (document.isNull() || document.d->type != NodeImpl::Document) return engine->undefinedValue();

    return QScriptValue(static_cast<DocumentImpl *>(document.d)->version);
}

QScriptValue Document::xmlEncoding(QScriptContext *context, QScriptEngine *engine)
{
    Node document = qscriptvalue_cast<Node>(context->thisObject());
    if (document.isNull() || document.d->type != NodeImpl::Document) return engine->undefinedValue();

    return QScriptValue(static_cast<DocumentImpl *>(document.d)->encoding);
}

class QDeclarativeXMLHttpRequest : public QObject
{
Q_OBJECT
public:
    enum State { Unsent = 0, 
                 Opened = 1, HeadersReceived = 2,
                 Loading = 3, Done = 4 };

    QDeclarativeXMLHttpRequest(QNetworkAccessManager *manager);
    virtual ~QDeclarativeXMLHttpRequest();

    bool sendFlag() const;
    bool errorFlag() const;
    quint32 readyState() const;
    int replyStatus() const;
    QString replyStatusText() const;

    QScriptValue open(QScriptValue *me, const QString &, const QUrl &);

    void addHeader(const QString &, const QString &);
    QString header(const QString &name);
    QString headers();
    QScriptValue send(QScriptValue *me, const QByteArray &);
    QScriptValue abort(QScriptValue *me);

    QString responseBody();
    const QByteArray & rawResponseBody() const;
    bool receivedXml() const;
private slots:
    void downloadProgress(qint64);
    void error(QNetworkReply::NetworkError);
    void finished();

private:
    void requestFromUrl(const QUrl &url);

    State m_state;
    bool m_errorFlag;
    bool m_sendFlag;
    QString m_method;
    QUrl m_url;
    QByteArray m_responseEntityBody;
    QByteArray m_data;
    int m_redirectCount;

    typedef QPair<QByteArray, QByteArray> HeaderPair;
    typedef QList<HeaderPair> HeadersList;
    HeadersList m_headersList;
    void fillHeadersList();

    bool m_gotXml;
    QByteArray m_mime;
    QByteArray m_charset;
    QTextCodec *m_textCodec;
#ifndef QT_NO_TEXTCODEC
    QTextCodec* findTextCodec() const;
#endif
    void readEncoding();

    QScriptValue m_me; // Set to the data object while a send() is ongoing (to access the callback)

    QScriptValue dispatchCallback(QScriptValue *me);
    void printError(const QScriptValue&);

    int m_status;
    QString m_statusText;
    QNetworkRequest m_request;
    QDeclarativeGuard<QNetworkReply> m_network;
    void destroyNetwork();

    QNetworkAccessManager *m_nam;
    QNetworkAccessManager *networkAccessManager() { return m_nam; }
};

QDeclarativeXMLHttpRequest::QDeclarativeXMLHttpRequest(QNetworkAccessManager *manager)
: m_state(Unsent), m_errorFlag(false), m_sendFlag(false),
  m_redirectCount(0), m_gotXml(false), m_textCodec(0), m_network(0), m_nam(manager)
{
}

QDeclarativeXMLHttpRequest::~QDeclarativeXMLHttpRequest()
{
    destroyNetwork();
}

bool QDeclarativeXMLHttpRequest::sendFlag() const
{
    return m_sendFlag;
}

bool QDeclarativeXMLHttpRequest::errorFlag() const
{
    return m_errorFlag;
}

quint32 QDeclarativeXMLHttpRequest::readyState() const
{
    return m_state;
}

int QDeclarativeXMLHttpRequest::replyStatus() const
{
    return m_status;
}

QString QDeclarativeXMLHttpRequest::replyStatusText() const
{
    return m_statusText;
}

QScriptValue QDeclarativeXMLHttpRequest::open(QScriptValue *me, const QString &method, const QUrl &url)
{
    destroyNetwork();
    m_sendFlag = false;
    m_errorFlag = false;
    m_responseEntityBody = QByteArray();
    m_method = method;
    m_url = url;
    m_state = Opened;
    return dispatchCallback(me);
}

void QDeclarativeXMLHttpRequest::addHeader(const QString &name, const QString &value)
{
    QByteArray utfname = name.toUtf8();

    if (m_request.hasRawHeader(utfname)) {
        m_request.setRawHeader(utfname, m_request.rawHeader(utfname) + ',' + value.toUtf8());
    } else {
        m_request.setRawHeader(utfname, value.toUtf8());
    }
}

QString QDeclarativeXMLHttpRequest::header(const QString &name)
{
    QByteArray utfname = name.toLower().toUtf8();

    foreach (const HeaderPair &header, m_headersList) {
        if (header.first == utfname)
            return QString::fromUtf8(header.second);
    }
    return QString();
}

QString QDeclarativeXMLHttpRequest::headers()
{
    QString ret;

    foreach (const HeaderPair &header, m_headersList) {
        if (ret.length())
            ret.append(QString::fromUtf8("\r\n"));
        ret.append(QString::fromUtf8(header.first));
        ret.append(QString::fromUtf8(": "));
        ret.append(QString::fromUtf8(header.second));
    }
    return ret;
}

void QDeclarativeXMLHttpRequest::fillHeadersList()
{
    QList<QByteArray> headerList = m_network->rawHeaderList();

    m_headersList.clear();
    foreach (const QByteArray &header, headerList) {
        HeaderPair pair (header.toLower(), m_network->rawHeader(header));
	if (pair.first == "set-cookie" ||
	    pair.first == "set-cookie2") 
	    continue;

        m_headersList << pair;
    }
}

void QDeclarativeXMLHttpRequest::requestFromUrl(const QUrl &url)
{
    QNetworkRequest request = m_request;
    request.setUrl(url);
    if(m_method == QLatin1String("POST") ||
       m_method == QLatin1String("PUT")) {
        QVariant var = request.header(QNetworkRequest::ContentTypeHeader);
        if (var.isValid()) {
            QString str = var.toString();
            int charsetIdx = str.indexOf(QLatin1String("charset="));
            if (charsetIdx == -1) {
                // No charset - append
                if (!str.isEmpty()) str.append(QLatin1Char(';'));
                str.append(QLatin1String("charset=UTF-8"));
            } else {
                charsetIdx += 8;
                int n = 0;
                int semiColon = str.indexOf(QLatin1Char(';'), charsetIdx);
                if (semiColon == -1) {
                    n = str.length() - charsetIdx;
                } else {
                    n = semiColon - charsetIdx;
                }

                str.replace(charsetIdx, n, QLatin1String("UTF-8"));
            }
            request.setHeader(QNetworkRequest::ContentTypeHeader, str);
        } else {
            request.setHeader(QNetworkRequest::ContentTypeHeader, 
                              QLatin1String("text/plain;charset=UTF-8"));
        }
    }

    if (xhrDump()) {
        qWarning().nospace() << "XMLHttpRequest: " << qPrintable(m_method) << " " << qPrintable(url.toString());
        if (!m_data.isEmpty()) {
            qWarning().nospace() << "                " 
                                 << qPrintable(QString::fromUtf8(m_data));
        }
    }

    if (m_method == QLatin1String("GET"))
        m_network = networkAccessManager()->get(request);
    else if (m_method == QLatin1String("HEAD"))
        m_network = networkAccessManager()->head(request);
    else if(m_method == QLatin1String("POST"))
        m_network = networkAccessManager()->post(request, m_data);
    else if(m_method == QLatin1String("PUT"))
        m_network = networkAccessManager()->put(request, m_data);

    QObject::connect(m_network, SIGNAL(downloadProgress(qint64,qint64)), 
                     this, SLOT(downloadProgress(qint64)));
    QObject::connect(m_network, SIGNAL(error(QNetworkReply::NetworkError)),
                     this, SLOT(error(QNetworkReply::NetworkError)));
    QObject::connect(m_network, SIGNAL(finished()),
                     this, SLOT(finished()));
}

QScriptValue QDeclarativeXMLHttpRequest::send(QScriptValue *me, const QByteArray &data)
{
    m_errorFlag = false;
    m_sendFlag = true;
    m_redirectCount = 0;
    m_data = data;
    m_me = *me;

    requestFromUrl(m_url);

    return QScriptValue();
}

QScriptValue QDeclarativeXMLHttpRequest::abort(QScriptValue *me)
{
    destroyNetwork();
    m_responseEntityBody = QByteArray();
    m_errorFlag = true;
    m_request = QNetworkRequest();

    if (!(m_state == Unsent || 
          (m_state == Opened && !m_sendFlag) ||
          m_state == Done)) {

        m_state = Done;
        m_sendFlag = false;
        QScriptValue cbv = dispatchCallback(me);
        if (cbv.isError()) return cbv;
    }

    m_state = Unsent;
    return QScriptValue();
}

void QDeclarativeXMLHttpRequest::downloadProgress(qint64 bytes)
{
    Q_UNUSED(bytes)
    m_status = 
        m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    m_statusText =
        QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());

    // ### We assume if this is called the headers are now available
    if (m_state < HeadersReceived) {
        m_state = HeadersReceived;
        fillHeadersList ();
        QScriptValue cbv = dispatchCallback(&m_me);
        if (cbv.isError()) printError(cbv);
    }

    bool wasEmpty = m_responseEntityBody.isEmpty();
    m_responseEntityBody.append(m_network->readAll());
    if (wasEmpty && !m_responseEntityBody.isEmpty()) {
        m_state = Loading;
        QScriptValue cbv = dispatchCallback(&m_me);
        if (cbv.isError()) printError(cbv);
    }
}

void QDeclarativeXMLHttpRequest::error(QNetworkReply::NetworkError error)
{
    Q_UNUSED(error)
    m_status =
        m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    m_statusText =
        QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());

    m_responseEntityBody = QByteArray();

    m_request = QNetworkRequest();
    m_data.clear();
    destroyNetwork();

    if (error == QNetworkReply::ContentAccessDenied ||
        error == QNetworkReply::ContentOperationNotPermittedError ||
        error == QNetworkReply::ContentNotFoundError ||
        error == QNetworkReply::AuthenticationRequiredError ||
        error == QNetworkReply::ContentReSendError) {
        m_state = Loading;
        QScriptValue cbv = dispatchCallback(&m_me);
        if (cbv.isError()) printError(cbv);
    } else {
        m_errorFlag = true;
    } 

    m_state = Done;
    QScriptValue cbv = dispatchCallback(&m_me);
    if (cbv.isError()) printError(cbv);
}

#define XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION 15
void QDeclarativeXMLHttpRequest::finished()
{
    m_redirectCount++;
    if (m_redirectCount < XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION) {
        QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
        if (redirect.isValid()) {
            QUrl url = m_network->url().resolved(redirect.toUrl());
            destroyNetwork();
            requestFromUrl(url);
            return;
        }
    }

    m_status =
        m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    m_statusText =
        QString::fromUtf8(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());

    if (m_state < HeadersReceived) {
        m_state = HeadersReceived;
        fillHeadersList ();
        QScriptValue cbv = dispatchCallback(&m_me);
        if (cbv.isError()) printError(cbv);
    }
    m_responseEntityBody.append(m_network->readAll());
    readEncoding();

    if (xhrDump()) {
        qWarning().nospace() << "XMLHttpRequest: RESPONSE " << qPrintable(m_url.toString());
        if (!m_responseEntityBody.isEmpty()) {
            qWarning().nospace() << "                " 
                                 << qPrintable(QString::fromUtf8(m_responseEntityBody));
        }
    }


    m_data.clear();
    destroyNetwork();
    if (m_state < Loading) {
        m_state = Loading;
        QScriptValue cbv = dispatchCallback(&m_me);
        if (cbv.isError()) printError(cbv);
    }
    m_state = Done;
    QScriptValue cbv = dispatchCallback(&m_me);
    if (cbv.isError()) printError(cbv);

    m_me = QScriptValue();
}


void QDeclarativeXMLHttpRequest::readEncoding()
{
    foreach (const HeaderPair &header, m_headersList) {
        if (header.first == "content-type") {
            int separatorIdx = header.second.indexOf(';');
            if (separatorIdx == -1) {
                m_mime == header.second;
            } else {
                m_mime = header.second.mid(0, separatorIdx);
                int charsetIdx = header.second.indexOf("charset=");
                if (charsetIdx != -1) {
                    charsetIdx += 8;
                    separatorIdx = header.second.indexOf(';', charsetIdx);
                    m_charset = header.second.mid(charsetIdx, separatorIdx >= 0 ? separatorIdx : header.second.length());
                }
            }
            break;
        }
    }

    if (m_mime.isEmpty() || m_mime == "text/xml" || m_mime == "application/xml" || m_mime.endsWith("+xml")) 
        m_gotXml = true;
}

bool QDeclarativeXMLHttpRequest::receivedXml() const
{
    return m_gotXml;
}


#ifndef QT_NO_TEXTCODEC
QTextCodec* QDeclarativeXMLHttpRequest::findTextCodec() const
{
    QTextCodec *codec = 0;

    if (!m_charset.isEmpty()) 
        codec = QTextCodec::codecForName(m_charset);

    if (!codec && m_gotXml) {
        QXmlStreamReader reader(m_responseEntityBody);
        reader.readNext();
        codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8());
    }

    if (!codec && m_mime == "text/html") 
        codec = QTextCodec::codecForHtml(m_responseEntityBody, 0);

    if (!codec)
        codec = QTextCodec::codecForUtfText(m_responseEntityBody, 0);

    if (!codec)
        codec = QTextCodec::codecForName("UTF-8");
    return codec;
}
#endif


QString QDeclarativeXMLHttpRequest::responseBody()
{
#ifndef QT_NO_TEXTCODEC
    if (!m_textCodec)
        m_textCodec = findTextCodec();
    if (m_textCodec)
        return m_textCodec->toUnicode(m_responseEntityBody);
#endif

    return QString::fromUtf8(m_responseEntityBody);
}

const QByteArray &QDeclarativeXMLHttpRequest::rawResponseBody() const
{
    return m_responseEntityBody;
}

QScriptValue QDeclarativeXMLHttpRequest::dispatchCallback(QScriptValue *me)
{
    QScriptValue v = me->property(QLatin1String("callback"));
    return v.call();
}

void QDeclarativeXMLHttpRequest::printError(const QScriptValue& sv)
{
    QDeclarativeError error;
    QDeclarativeExpressionPrivate::exceptionToError(sv.engine(), error);
    QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate::get(sv.engine()), error);
}

void QDeclarativeXMLHttpRequest::destroyNetwork()
{
    if (m_network) {
        m_network->disconnect();
        m_network->deleteLater();
        m_network = 0;
    }
}

// XMLHttpRequest methods
static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngine *engine)
{
    QScriptValue dataObject = context->thisObject().data();
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(dataObject.toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (context->argumentCount() < 2 || context->argumentCount() > 5)
        THROW_DOM(SYNTAX_ERR, "Incorrect argument count");

    // Argument 0 - Method
    QString method = context->argument(0).toString().toUpper();
    if (method != QLatin1String("GET") && 
        method != QLatin1String("PUT") &&
        method != QLatin1String("HEAD") &&
        method != QLatin1String("POST"))
        THROW_DOM(SYNTAX_ERR, "Unsupported HTTP method type");


    // Argument 1 - URL
    QUrl url = QUrl::fromEncoded(context->argument(1).toString().toUtf8());

    if (url.isRelative()) {
        url = QDeclarativeScriptEngine::get(engine)->resolvedUrl(context,url);
    }

    // Argument 2 - async (optional)
    if (context->argumentCount() > 2 && !context->argument(2).toBoolean())
        THROW_DOM(NOT_SUPPORTED_ERR, "Synchronous XMLHttpRequest calls are not supported");


    // Argument 3/4 - user/pass (optional)
    QString username, password;
    if (context->argumentCount() > 3)
        username = context->argument(3).toString();
    if (context->argumentCount() > 4)
        password = context->argument(4).toString();


    // Clear the fragment (if any)
    url.setFragment(QString());
    // Set username/password
    if (!username.isNull()) url.setUserName(username);
    if (!password.isNull()) url.setPassword(password);

    return request->open(&dataObject, method, url);
}

static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, QScriptEngine *engine)
{
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (context->argumentCount() != 2)
        THROW_DOM(SYNTAX_ERR, "Incorrect argument count");


    if (request->readyState() != QDeclarativeXMLHttpRequest::Opened ||
        request->sendFlag())
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");


    QString name = context->argument(0).toString();
    QString value = context->argument(1).toString();

    // ### Check that name and value are well formed

    QString nameUpper = name.toUpper();
    if (nameUpper == QLatin1String("ACCEPT-CHARSET") ||
        nameUpper == QLatin1String("ACCEPT-ENCODING") ||
        nameUpper == QLatin1String("CONNECTION") ||
        nameUpper == QLatin1String("CONTENT-LENGTH") ||
        nameUpper == QLatin1String("COOKIE") ||
        nameUpper == QLatin1String("COOKIE2") ||
        nameUpper == QLatin1String("CONTENT-TRANSFER-ENCODING") ||
        nameUpper == QLatin1String("DATE") ||
        nameUpper == QLatin1String("EXPECT") ||
        nameUpper == QLatin1String("HOST") ||
        nameUpper == QLatin1String("KEEP-ALIVE") ||
        nameUpper == QLatin1String("REFERER") ||
        nameUpper == QLatin1String("TE") ||
        nameUpper == QLatin1String("TRAILER") ||
        nameUpper == QLatin1String("TRANSFER-ENCODING") ||
        nameUpper == QLatin1String("UPGRADE") ||
        nameUpper == QLatin1String("USER-AGENT") ||
        nameUpper == QLatin1String("VIA") ||
        nameUpper.startsWith(QLatin1String("PROXY-")) ||
        nameUpper.startsWith(QLatin1String("SEC-"))) 
        return engine->undefinedValue();

    request->addHeader(nameUpper, value);

    return engine->undefinedValue();
}

static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *)
{
    QScriptValue dataObject = context->thisObject().data();
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(dataObject.toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (request->readyState() != QDeclarativeXMLHttpRequest::Opened)
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    if (request->sendFlag())
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    QByteArray data;
    if (context->argumentCount() > 0)
        data = context->argument(0).toString().toUtf8();

    return request->send(&dataObject, data);
}

static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngine *)
{
    QScriptValue dataObject = context->thisObject().data();
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(dataObject.toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    return request->abort(&dataObject);
}

static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (context->argumentCount() != 1)
        THROW_DOM(SYNTAX_ERR, "Incorrect argument count");

    if (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
        request->readyState() != QDeclarativeXMLHttpRequest::Done &&
        request->readyState() != QDeclarativeXMLHttpRequest::HeadersReceived)
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    QString headerName = context->argument(0).toString();

    return QScriptValue(request->header(headerName));
}

static QScriptValue qmlxmlhttprequest_getAllResponseHeaders(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (context->argumentCount() != 0)
        THROW_DOM(SYNTAX_ERR, "Incorrect argument count");

    if (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
        request->readyState() != QDeclarativeXMLHttpRequest::Done &&
        request->readyState() != QDeclarativeXMLHttpRequest::HeadersReceived)
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    return QScriptValue(request->headers());
}

// XMLHttpRequest properties
static QScriptValue qmlxmlhttprequest_readyState(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    return QScriptValue(request->readyState());
}

static QScriptValue qmlxmlhttprequest_status(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (request->readyState() == QDeclarativeXMLHttpRequest::Unsent ||
        request->readyState() == QDeclarativeXMLHttpRequest::Opened)
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    if (request->errorFlag())
        return QScriptValue(0);
    else
        return QScriptValue(request->replyStatus());
}

static QScriptValue qmlxmlhttprequest_statusText(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (request->readyState() == QDeclarativeXMLHttpRequest::Unsent ||
        request->readyState() == QDeclarativeXMLHttpRequest::Opened)
        THROW_DOM(INVALID_STATE_ERR, "Invalid state");

    if (request->errorFlag())
        return QScriptValue(0);
    else
        return QScriptValue(request->replyStatusText());
}

static QScriptValue qmlxmlhttprequest_responseText(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine)
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
        request->readyState() != QDeclarativeXMLHttpRequest::Done)
        return QScriptValue(QString());
    else 
        return QScriptValue(request->responseBody());
}

static QScriptValue qmlxmlhttprequest_responseXML(QScriptContext *context, QScriptEngine *engine)
{
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(context->thisObject().data().toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (!request->receivedXml() ||
        (request->readyState() != QDeclarativeXMLHttpRequest::Loading &&
         request->readyState() != QDeclarativeXMLHttpRequest::Done))
        return engine->nullValue();
    else  
        return Document::load(engine, request->rawResponseBody());
}

static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    QScriptValue dataObject = context->thisObject().data();
    QDeclarativeXMLHttpRequest *request = qobject_cast<QDeclarativeXMLHttpRequest *>(dataObject.toQObject());
    if (!request) 
        THROW_REFERENCE("Not an XMLHttpRequest object");

    if (context->argumentCount()) {
        QScriptValue v = context->argument(0);
        dataObject.setProperty(QLatin1String("callback"), v);
        return v;
    } else {
        return dataObject.property(QLatin1String("callback"));
    }
}

// Constructor
static QScriptValue qmlxmlhttprequest_new(QScriptContext *context, QScriptEngine *engine)
{
    if (context->isCalledAsConstructor()) {
        context->thisObject().setData(engine->newQObject(new QDeclarativeXMLHttpRequest(QDeclarativeScriptEngine::get(engine)->networkAccessManager()), QScriptEngine::ScriptOwnership));
    }
    return engine->undefinedValue();
}

void qt_add_qmlxmlhttprequest(QScriptEngine *engine)
{
    QScriptValue prototype = engine->newObject();

    // Methods
    prototype.setProperty(QLatin1String("open"), engine->newFunction(qmlxmlhttprequest_open, 2));
    prototype.setProperty(QLatin1String("setRequestHeader"), engine->newFunction(qmlxmlhttprequest_setRequestHeader, 2));
    prototype.setProperty(QLatin1String("send"), engine->newFunction(qmlxmlhttprequest_send));
    prototype.setProperty(QLatin1String("abort"), engine->newFunction(qmlxmlhttprequest_abort));
    prototype.setProperty(QLatin1String("getResponseHeader"), engine->newFunction(qmlxmlhttprequest_getResponseHeader, 1));
    prototype.setProperty(QLatin1String("getAllResponseHeaders"), engine->newFunction(qmlxmlhttprequest_getAllResponseHeaders));

    // Read-only properties
    prototype.setProperty(QLatin1String("readyState"), engine->newFunction(qmlxmlhttprequest_readyState), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    prototype.setProperty(QLatin1String("status"), engine->newFunction(qmlxmlhttprequest_status), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    prototype.setProperty(QLatin1String("statusText"), engine->newFunction(qmlxmlhttprequest_statusText), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    prototype.setProperty(QLatin1String("responseText"), engine->newFunction(qmlxmlhttprequest_responseText), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    prototype.setProperty(QLatin1String("responseXML"), engine->newFunction(qmlxmlhttprequest_responseXML), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
    prototype.setProperty(QLatin1String("onreadystatechange"), engine->newFunction(qmlxmlhttprequest_onreadystatechange), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);

    // State values
    prototype.setProperty(QLatin1String("UNSENT"), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    prototype.setProperty(QLatin1String("OPENED"), 1, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    prototype.setProperty(QLatin1String("HEADERS_RECEIVED"), 2, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    prototype.setProperty(QLatin1String("LOADING"), 3, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    prototype.setProperty(QLatin1String("DONE"), 4, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);

    // Constructor
    QScriptValue constructor = engine->newFunction(qmlxmlhttprequest_new, prototype);
    constructor.setProperty(QLatin1String("UNSENT"), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    constructor.setProperty(QLatin1String("OPENED"), 1, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    constructor.setProperty(QLatin1String("HEADERS_RECEIVED"), 2, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    constructor.setProperty(QLatin1String("LOADING"), 3, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    constructor.setProperty(QLatin1String("DONE"), 4, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    engine->globalObject().setProperty(QLatin1String("XMLHttpRequest"), constructor);

    // DOM Exception
    QScriptValue domExceptionPrototype = engine->newObject();
    domExceptionPrototype.setProperty(QLatin1String("INDEX_SIZE_ERR"), INDEX_SIZE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("DOMSTRING_SIZE_ERR"), DOMSTRING_SIZE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("HIERARCHY_REQUEST_ERR"), HIERARCHY_REQUEST_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("WRONG_DOCUMENT_ERR"), WRONG_DOCUMENT_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("INVALID_CHARACTER_ERR"), INVALID_CHARACTER_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("NO_DATA_ALLOWED_ERR"), NO_DATA_ALLOWED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("NO_MODIFICATION_ALLOWED_ERR"), NO_MODIFICATION_ALLOWED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("NOT_FOUND_ERR"), NOT_FOUND_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("NOT_SUPPORTED_ERR"), NOT_SUPPORTED_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("INUSE_ATTRIBUTE_ERR"), INUSE_ATTRIBUTE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("INVALID_STATE_ERR"), INVALID_STATE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("SYNTAX_ERR"), SYNTAX_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("INVALID_MODIFICATION_ERR"), INVALID_MODIFICATION_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("NAMESPACE_ERR"), NAMESPACE_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("INVALID_ACCESS_ERR"), INVALID_ACCESS_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("VALIDATION_ERR"), VALIDATION_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
    domExceptionPrototype.setProperty(QLatin1String("TYPE_MISMATCH_ERR"), TYPE_MISMATCH_ERR, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);

    engine->globalObject().setProperty(QLatin1String("DOMException"), domExceptionPrototype);
}

QT_END_NAMESPACE

#endif // QT_NO_XMLSTREAMREADER

#include <qdeclarativexmlhttprequest.moc>
