/****************************************************************************
**
** 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/qdeclarativeenginedebug_p.h"

#include "private/qdeclarativeboundsignal_p.h"
#include "qdeclarativeengine.h"
#include "private/qdeclarativemetatype_p.h"
#include "qdeclarativeproperty.h"
#include "private/qdeclarativeproperty_p.h"
#include "private/qdeclarativebinding_p.h"
#include "private/qdeclarativecontext_p.h"
#include "private/qdeclarativewatcher_p.h"
#include "private/qdeclarativevaluetype_p.h"
#include "private/qdeclarativevmemetaobject_p.h"
#include "private/qdeclarativeexpression_p.h"
#include "private/qdeclarativepropertychanges_p.h"

#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>

QT_BEGIN_NAMESPACE

Q_GLOBAL_STATIC(QDeclarativeEngineDebugServer, qmlEngineDebugServer);

QDeclarativeEngineDebugServer *QDeclarativeEngineDebugServer::instance()
{
    return qmlEngineDebugServer();
}

QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent)
: QDeclarativeDebugService(QLatin1String("QDeclarativeEngine"), parent),
    m_watch(new QDeclarativeWatcher(this))
{
    QObject::connect(m_watch, SIGNAL(propertyChanged(int,int,QMetaProperty,QVariant)),
                     this, SLOT(propertyChanged(int,int,QMetaProperty,QVariant)));
}

QDataStream &operator<<(QDataStream &ds, 
                        const QDeclarativeEngineDebugServer::QDeclarativeObjectData &data)
{
    ds << data.url << data.lineNumber << data.columnNumber << data.idString
       << data.objectName << data.objectType << data.objectId << data.contextId;
    return ds;
}

QDataStream &operator>>(QDataStream &ds, 
                        QDeclarativeEngineDebugServer::QDeclarativeObjectData &data)
{
    ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
       >> data.objectName >> data.objectType >> data.objectId >> data.contextId;
    return ds;
}

QDataStream &operator<<(QDataStream &ds, 
                        const QDeclarativeEngineDebugServer::QDeclarativeObjectProperty &data)
{
    ds << (int)data.type << data.name << data.value << data.valueTypeName
       << data.binding << data.hasNotifySignal;
    return ds;
}

QDataStream &operator>>(QDataStream &ds,  
                        QDeclarativeEngineDebugServer::QDeclarativeObjectProperty &data)
{
    int type;
    ds >> type >> data.name >> data.value >> data.valueTypeName
       >> data.binding >> data.hasNotifySignal;
    data.type = (QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Type)type;
    return ds;
}

static inline bool isSignalPropertyName(const QString &signalName)
{
    // see QmlCompiler::isSignalPropertyName
    return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) &&
           signalName.at(2).isLetter() && signalName.at(2).isUpper();
}

static bool hasValidSignal(QObject *object, const QString &propertyName)
{
    if (!isSignalPropertyName(propertyName))
        return false;

    QString signalName = propertyName.mid(2);
    signalName[0] = signalName.at(0).toLower();

    int sigIdx = QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), signalName.toLatin1()).methodIndex();

    if (sigIdx == -1)
        return false;

    return true;
}

QDeclarativeEngineDebugServer::QDeclarativeObjectProperty 
QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx)
{
    QDeclarativeObjectProperty rv;

    QMetaProperty prop = obj->metaObject()->property(propIdx);

    rv.type = QDeclarativeObjectProperty::Unknown;
    rv.valueTypeName = QString::fromUtf8(prop.typeName());
    rv.name = QString::fromUtf8(prop.name());
    rv.hasNotifySignal = prop.hasNotifySignal();
    QDeclarativeAbstractBinding *binding = 
        QDeclarativePropertyPrivate::binding(QDeclarativeProperty(obj, rv.name));
    if (binding)
        rv.binding = binding->expression();

    QVariant value;
    if (prop.userType() != 0) {
        value = prop.read(obj);
    }
    rv.value = valueContents(value);

    if (QDeclarativeValueTypeFactory::isValueType(prop.userType())) {
        rv.type = QDeclarativeObjectProperty::Basic;
    } else if (QDeclarativeMetaType::isQObject(prop.userType()))  {
        rv.type = QDeclarativeObjectProperty::Object;
    } else if (QDeclarativeMetaType::isList(prop.userType())) {
        rv.type = QDeclarativeObjectProperty::List;
    }

    return rv;
}

QVariant QDeclarativeEngineDebugServer::valueContents(const QVariant &value) const
{
    int userType = value.userType();

    if (value.type() == QVariant::List) {
        QVariantList contents;
        QVariantList list = value.toList();
        int count = list.size();
        for (int i = 0; i < count; i++)
            contents << valueContents(list.at(i));
        return contents;
    }

    if (QDeclarativeValueTypeFactory::isValueType(userType))
        return value;

    if (QDeclarativeMetaType::isQObject(userType)) {
        QObject *o = QDeclarativeMetaType::toQObject(value);
        if (o) {
            QString name = o->objectName();
            if (name.isEmpty())
                name = QLatin1String("<unnamed object>");
            return name;
        }
    }

    return QLatin1String("<unknown value>");
}

void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message, 
                                           QObject *object, bool recur, bool dumpProperties)
{
    message << objectData(object);

    QObjectList children = object->children();
    
    int childrenCount = children.count();
    for (int ii = 0; ii < children.count(); ++ii) {
        if (qobject_cast<QDeclarativeContext*>(children[ii]) || QDeclarativeBoundSignal::cast(children[ii]))
            --childrenCount;
    }

    message << childrenCount << recur;

    QList<QDeclarativeObjectProperty> fakeProperties;

    for (int ii = 0; ii < children.count(); ++ii) {
        QObject *child = children.at(ii);
        if (qobject_cast<QDeclarativeContext*>(child))
            continue;
        QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child);
        if (signal) {
            if (!dumpProperties)
                continue;
            QDeclarativeObjectProperty prop;
            prop.type = QDeclarativeObjectProperty::SignalProperty;
            prop.hasNotifySignal = false;
            QDeclarativeExpression *expr = signal->expression();
            if (expr) {
                prop.value = expr->expression();
                QObject *scope = expr->scopeObject();
                if (scope) {
                    QString sig = QLatin1String(scope->metaObject()->method(signal->index()).signature());
                    int lparen = sig.indexOf(QLatin1Char('('));
                    if (lparen >= 0) {
                        QString methodName = sig.mid(0, lparen);
                        prop.name = QLatin1String("on") + methodName[0].toUpper()
                                + methodName.mid(1);
                    }
                }
            }
            fakeProperties << prop;
        } else {
            if (recur)
                buildObjectDump(message, child, recur, dumpProperties);
            else
                message << objectData(child);
        }
    }

    if (!dumpProperties) {
        message << 0;
        return;
    }

    QList<int> propertyIndexes;
    for (int ii = 0; ii < object->metaObject()->propertyCount(); ++ii) {
        if (object->metaObject()->property(ii).isScriptable())
            propertyIndexes << ii;
    }

    message << propertyIndexes.size() + fakeProperties.count();

    for (int ii = 0; ii < propertyIndexes.size(); ++ii)
        message << propertyData(object, propertyIndexes.at(ii));

    for (int ii = 0; ii < fakeProperties.count(); ++ii)
        message << fakeProperties[ii];
}

void QDeclarativeEngineDebugServer::prepareDeferredObjects(QObject *obj)
{
    qmlExecuteDeferred(obj);

    QObjectList children = obj->children();
    for (int ii = 0; ii < children.count(); ++ii) {
        QObject *child = children.at(ii);
        prepareDeferredObjects(child);
    }

}

void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt)
{
    QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt);

    QString ctxtName = ctxt->objectName();
    int ctxtId = QDeclarativeDebugService::idForObject(ctxt);

    message << ctxtName << ctxtId; 

    int count = 0;

    QDeclarativeContextData *child = p->childContexts;
    while (child) {
        ++count;
        child = child->nextChild;
    }

    message << count;

    child = p->childContexts;
    while (child) {
        buildObjectList(message, child->asQDeclarativeContext());
        child = child->nextChild;
    }

    // Clean deleted objects
    QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
    for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
        if (!ctxtPriv->instances.at(ii)) {
            ctxtPriv->instances.removeAt(ii);
            --ii;
        }
    }

    message << ctxtPriv->instances.count();
    for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
        message << objectData(ctxtPriv->instances.at(ii));
    }
}

void QDeclarativeEngineDebugServer::buildStatesList(QDeclarativeContext *ctxt, bool cleanList=false)
{
    if (cleanList)
        m_allStates.clear();

    QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
    for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
        buildStatesList(ctxtPriv->instances.at(ii));
    }

    QDeclarativeContextData *child = QDeclarativeContextData::get(ctxt)->childContexts;
    while (child) {
        buildStatesList(child->asQDeclarativeContext());
        child = child->nextChild;
    }
}

void QDeclarativeEngineDebugServer::buildStatesList(QObject *obj)
{
    if (QDeclarativeState *state = qobject_cast<QDeclarativeState *>(obj)) {
            m_allStates.append(state);
    }

    QObjectList children = obj->children();
    for (int ii = 0; ii < children.count(); ++ii) {
        buildStatesList(children.at(ii));
    }
}

QDeclarativeEngineDebugServer::QDeclarativeObjectData 
QDeclarativeEngineDebugServer::objectData(QObject *object)
{
    QDeclarativeData *ddata = QDeclarativeData::get(object);
    QDeclarativeObjectData rv;
    if (ddata && ddata->outerContext) {
        rv.url = ddata->outerContext->url;
        rv.lineNumber = ddata->lineNumber;
        rv.columnNumber = ddata->columnNumber;
    } else {
        rv.lineNumber = -1;
        rv.columnNumber = -1;
    }

    QDeclarativeContext *context = qmlContext(object);
    if (context) {
        QDeclarativeContextData *cdata = QDeclarativeContextData::get(context);
        if (cdata)
            rv.idString = cdata->findObjectId(object);
    }

    rv.objectName = object->objectName();
    rv.objectId = QDeclarativeDebugService::idForObject(object);
    rv.contextId = QDeclarativeDebugService::idForObject(qmlContext(object));

    QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
    if (type) {
        QString typeName = QLatin1String(type->qmlTypeName());
        int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
        rv.objectType = lastSlash < 0 ? typeName : typeName.mid(lastSlash+1);
    } else {
        rv.objectType = QString::fromUtf8(object->metaObject()->className());
        int marker = rv.objectType.indexOf(QLatin1String("_QMLTYPE_"));
        if (marker != -1)
            rv.objectType = rv.objectType.left(marker);
    }

    return rv;
}

void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
{
    QDataStream ds(message);

    QByteArray type;
    ds >> type;

    if (type == "LIST_ENGINES") {
        int queryId;
        ds >> queryId;

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("LIST_ENGINES_R");
        rs << queryId << m_engines.count();

        for (int ii = 0; ii < m_engines.count(); ++ii) {
            QDeclarativeEngine *engine = m_engines.at(ii);

            QString engineName = engine->objectName();
            int engineId = QDeclarativeDebugService::idForObject(engine);

            rs << engineName << engineId;
        }

        sendMessage(reply);
    } else if (type == "LIST_OBJECTS") {
        int queryId;
        int engineId = -1;
        ds >> queryId >> engineId;

        QDeclarativeEngine *engine = 
            qobject_cast<QDeclarativeEngine *>(QDeclarativeDebugService::objectForId(engineId));

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("LIST_OBJECTS_R") << queryId;

        if (engine) {
            buildObjectList(rs, engine->rootContext());
            buildStatesList(engine->rootContext(), true);
        }

        sendMessage(reply);
    } else if (type == "FETCH_OBJECT") {
        int queryId;
        int objectId;
        bool recurse;
        bool dumpProperties = true;

        ds >> queryId >> objectId >> recurse >> dumpProperties;

        QObject *object = QDeclarativeDebugService::objectForId(objectId);

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("FETCH_OBJECT_R") << queryId;

        if (object) {
            if (recurse)
                prepareDeferredObjects(object);
            buildObjectDump(rs, object, recurse, dumpProperties);
        }

        sendMessage(reply);
    } else if (type == "WATCH_OBJECT") {
        int queryId;
        int objectId;

        ds >> queryId >> objectId;
        bool ok = m_watch->addWatch(queryId, objectId);

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("WATCH_OBJECT_R") << queryId << ok;

        sendMessage(reply);
    } else if (type == "WATCH_PROPERTY") {
        int queryId;
        int objectId;
        QByteArray property;

        ds >> queryId >> objectId >> property;
        bool ok = m_watch->addWatch(queryId, objectId, property);

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("WATCH_PROPERTY_R") << queryId << ok;

        sendMessage(reply);
    } else if (type == "WATCH_EXPR_OBJECT") {
        int queryId;
        int debugId;
        QString expr;

        ds >> queryId >> debugId >> expr;
        bool ok = m_watch->addWatch(queryId, debugId, expr);

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok;
        sendMessage(reply);
    } else if (type == "NO_WATCH") {
        int queryId;

        ds >> queryId;
        m_watch->removeWatch(queryId);
    } else if (type == "EVAL_EXPRESSION") {
        int queryId;
        int objectId;
        QString expr;

        ds >> queryId >> objectId >> expr;

        QObject *object = QDeclarativeDebugService::objectForId(objectId);
        QDeclarativeContext *context = qmlContext(object);
        QVariant result;
        if (object && context) {
            QDeclarativeExpression exprObj(context, object, expr);
            bool undefined = false;
            QVariant value = exprObj.evaluate(&undefined);
            if (undefined)
                result = QLatin1String("<undefined>");
            else
                result = valueContents(value);
        } else {
            result = QLatin1String("<unknown context>");
        }

        QByteArray reply;
        QDataStream rs(&reply, QIODevice::WriteOnly);
        rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result;

        sendMessage(reply);
    } else if (type == "SET_BINDING") {
        int objectId;
        QString propertyName;
        QVariant expr;
        bool isLiteralValue;
        ds >> objectId >> propertyName >> expr >> isLiteralValue;
        setBinding(objectId, propertyName, expr, isLiteralValue);
    } else if (type == "RESET_BINDING") {
        int objectId;
        QString propertyName;
        ds >> objectId >> propertyName;
        resetBinding(objectId, propertyName);
    } else if (type == "SET_METHOD_BODY") {
        int objectId;
        QString methodName;
        QString methodBody;
        ds >> objectId >> methodName >> methodBody;
        setMethodBody(objectId, methodName, methodBody);
    }
}

void QDeclarativeEngineDebugServer::setBinding(int objectId,
                                               const QString &propertyName,
                                               const QVariant &expression,
                                               bool isLiteralValue)
{
    QObject *object = objectForId(objectId);
    QDeclarativeContext *context = qmlContext(object);

    if (object && context) {
        QDeclarativeProperty property(object, propertyName, context);
        if (property.isValid()) {

            bool inBaseState = true;

            foreach(QWeakPointer<QDeclarativeState> statePointer, m_allStates) {
                if (QDeclarativeState *state = statePointer.data()) {
                    // here we assume that the revert list on itself defines the base state
                    if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) {
                        inBaseState = false;

                        QDeclarativeBinding *newBinding = 0;
                        if (!isLiteralValue) {
                            newBinding = new QDeclarativeBinding(expression.toString(), object, context);
                            newBinding->setTarget(property);
                            newBinding->setNotifyOnValueChanged(true);
                        }

                        state->changeBindingInRevertList(object, propertyName, newBinding);

                        if (isLiteralValue)
                            state->changeValueInRevertList(object, propertyName, expression);
                    }
                }
            }

            if (inBaseState) {
                if (isLiteralValue) {
                    property.write(expression);
                } else if (hasValidSignal(object, propertyName)) {
                    QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
                    QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
                    declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
                } else if (property.isProperty()) {
                    QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
                    binding->setTarget(property);
                    binding->setNotifyOnValueChanged(true);
                    QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
                    if (oldBinding)
                        oldBinding->destroy();
                    binding->update();
                } else {
                    qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
                }
            }

        } else {
            // not a valid property
            if (QDeclarativePropertyChanges *propertyChanges = qobject_cast<QDeclarativePropertyChanges *>(object)) {
                if (isLiteralValue) {
                    propertyChanges->changeValue(propertyName, expression);
                } else {
                    propertyChanges->changeExpression(propertyName, expression.toString());
                }
            } else {
                qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
            }
        }
    }
}

void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &propertyName)
{
    QObject *object = objectForId(objectId);
    QDeclarativeContext *context = qmlContext(object);

    if (object && context) {
        if (object->property(propertyName.toLatin1()).isValid()) {
            QDeclarativeProperty property(object, propertyName);
            QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(property);
            if (oldBinding) {
                QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, 0);
                if (oldBinding)
                    oldBinding->destroy();
            }
            if (property.isResettable()) {
                // Note: this will reset the property in any case, without regard to states
                // Right now almost no QDeclarativeItem has reset methods for its properties (with the
                // notable exception of QDeclarativeAnchors), so this is not a big issue
                // later on, setBinding does take states into account
                property.reset();
            } else {
                // overwrite with default value
                if (QDeclarativeType *objType = QDeclarativeMetaType::qmlType(object->metaObject())) {
                    if (QObject *emptyObject = objType->create()) {
                        if (emptyObject->property(propertyName.toLatin1()).isValid()) {
                            QVariant defaultValue = QDeclarativeProperty(emptyObject, propertyName).read();
                            if (defaultValue.isValid()) {
                                setBinding(objectId, propertyName, defaultValue, true);
                            }
                        }
                        delete emptyObject;
                    }
                }
            }
        } else {
            if (QDeclarativePropertyChanges *propertyChanges = qobject_cast<QDeclarativePropertyChanges *>(object)) {
                propertyChanges->removeProperty(propertyName);
            }
        }
    }
}

void QDeclarativeEngineDebugServer::setMethodBody(int objectId, const QString &method, const QString &body)
{
    QObject *object = objectForId(objectId);
    QDeclarativeContext *context = qmlContext(object);
    if (!object || !context || !context->engine())
        return;
    QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
    if (!contextData)
        return;

    QDeclarativePropertyCache::Data dummy;
    QDeclarativePropertyCache::Data *prop = 
        QDeclarativePropertyCache::property(context->engine(), object, method, dummy);

    if (!prop || !(prop->flags & QDeclarativePropertyCache::Data::IsVMEFunction))
        return;

    QMetaMethod metaMethod = object->metaObject()->method(prop->coreIndex);
    QList<QByteArray> paramNames = metaMethod.parameterNames();

    QString paramStr;
    for (int ii = 0; ii < paramNames.count(); ++ii) {
        if (ii != 0) paramStr.append(QLatin1String(","));
        paramStr.append(QString::fromUtf8(paramNames.at(ii)));
    }

    QString jsfunction = QLatin1String("(function ") + method + QLatin1String("(") + paramStr + 
                         QLatin1String(") {");
    jsfunction += body;
    jsfunction += QLatin1String("\n})");

    QDeclarativeVMEMetaObject *vmeMetaObject = 
        static_cast<QDeclarativeVMEMetaObject*>(QObjectPrivate::get(object)->metaObject);
    Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this

    int lineNumber = vmeMetaObject->vmeMethodLineNumber(prop->coreIndex);
    vmeMetaObject->setVmeMethod(prop->coreIndex, QDeclarativeExpressionPrivate::evalInObjectScope(contextData, object, jsfunction, contextData->url.toString(), lineNumber, 0));
}

void QDeclarativeEngineDebugServer::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value)
{
    QByteArray reply;
    QDataStream rs(&reply, QIODevice::WriteOnly);

    rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value);

    sendMessage(reply);
}

void QDeclarativeEngineDebugServer::addEngine(QDeclarativeEngine *engine)
{
    Q_ASSERT(engine);
    Q_ASSERT(!m_engines.contains(engine));

    m_engines.append(engine);
}

void QDeclarativeEngineDebugServer::remEngine(QDeclarativeEngine *engine)
{
    Q_ASSERT(engine);
    Q_ASSERT(m_engines.contains(engine));

    m_engines.removeAll(engine);
}

void QDeclarativeEngineDebugServer::objectCreated(QDeclarativeEngine *engine, QObject *object)
{
    Q_ASSERT(engine);
    Q_ASSERT(m_engines.contains(engine));

    int engineId = QDeclarativeDebugService::idForObject(engine);
    int objectId = QDeclarativeDebugService::idForObject(object);

    QByteArray reply;
    QDataStream rs(&reply, QIODevice::WriteOnly);

    rs << QByteArray("OBJECT_CREATED") << engineId << objectId;
    sendMessage(reply);
}

QT_END_NAMESPACE
