/****************************************************************************
**
** 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>
