/****************************************************************************
**
** 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 "qdeclarativeproperty.h"
#include "private/qdeclarativeproperty_p.h"

#include "qdeclarative.h"
#include "private/qdeclarativebinding_p.h"
#include "qdeclarativecontext.h"
#include "private/qdeclarativecontext_p.h"
#include "private/qdeclarativeboundsignal_p.h"
#include "qdeclarativeengine.h"
#include "private/qdeclarativeengine_p.h"
#include "private/qdeclarativedata_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativelist_p.h"
#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativevmemetaobject_p.h"

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

#include <math.h>

QT_BEGIN_NAMESPACE

/*!
\class QDeclarativeProperty
\since 4.7
\brief The QDeclarativeProperty class abstracts accessing properties on objects created from  QML.

As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect
and interact with objects created by QML.  However, some of the new features provided by QML - such 
as type safety and attached properties - are most easily used through the QDeclarativeProperty class 
that simplifies some of their natural complexity.

Unlike QMetaProperty which represents a property on a class type, QDeclarativeProperty encapsulates 
a property on a specific object instance.  To read a property's value, programmers create a 
QDeclarativeProperty instance and call the read() method.  Likewise to write a property value the
write() method is used.

For example, for the following QML code:

\qml
// MyItem.qml
import QtQuick 1.0

Text { text: "A bit of text" }
\endqml

The \l Text object's properties could be accessed using QDeclarativeProperty, like this:

\code
#include <QDeclarativeProperty>
#include <QGraphicsObject>

...

QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml"));
QDeclarativeProperty property(view.rootObject(), "font.pixelSize");
qWarning() << "Current pixel size:" << property.read().toInt();
property.write(24);
qWarning() << "Pixel size should now be 24:" << property.read().toInt();
\endcode
*/

/*!
    Create an invalid QDeclarativeProperty.
*/
QDeclarativeProperty::QDeclarativeProperty()
: d(0)
{
}

/*!  \internal */
QDeclarativeProperty::~QDeclarativeProperty()
{
    if (d)
        d->release();
    d = 0;
}

/*!
    Creates a QDeclarativeProperty for the default property of \a obj. If there is no
    default property, an invalid QDeclarativeProperty will be created.
 */
QDeclarativeProperty::QDeclarativeProperty(QObject *obj)
: d(new QDeclarativePropertyPrivate)
{
    d->initDefault(obj);
}

/*!
    Creates a QDeclarativeProperty for the default property of \a obj
    using the \l{QDeclarativeContext} {context} \a ctxt. If there is
    no default property, an invalid QDeclarativeProperty will be
    created.
 */
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ctxt)
: d(new QDeclarativePropertyPrivate)
{
    d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
    d->engine = ctxt?ctxt->engine():0;
    d->initDefault(obj);
}

/*!
    Creates a QDeclarativeProperty for the default property of \a obj
    using the environment for instantiating QML components that is
    provided by \a engine.  If there is no default property, an
    invalid QDeclarativeProperty will be created.
 */
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeEngine *engine)
  : d(new QDeclarativePropertyPrivate)
{
    d->context = 0;
    d->engine = engine;
    d->initDefault(obj);
}

/*!
    Initialize from the default property of \a obj
*/
void QDeclarativePropertyPrivate::initDefault(QObject *obj)
{
    if (!obj)
        return;

    QMetaProperty p = QDeclarativeMetaType::defaultProperty(obj);
    core.load(p);
    if (core.isValid()) 
        object = obj;
}

/*!
    Creates a QDeclarativeProperty for the property \a name of \a obj.
 */
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name)
: d(new QDeclarativePropertyPrivate)
{
    d->initProperty(obj, name);
    if (!isValid()) d->object = 0;
}

/*!
    Creates a QDeclarativeProperty for the property \a name of \a obj
    using the \l{QDeclarativeContext} {context} \a ctxt.
*/
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeContext *ctxt)
: d(new QDeclarativePropertyPrivate)
{
    d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
    d->engine = ctxt?ctxt->engine():0;
    d->initProperty(obj, name);
    if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
}

/*!
    Creates a QDeclarativeProperty for the property \a name of \a obj
    using the environment for instantiating QML components that is
    provided by \a engine.
 */
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeEngine *engine)
: d(new QDeclarativePropertyPrivate)
{
    d->context = 0;
    d->engine = engine;
    d->initProperty(obj, name);
    if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
}

Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes);

void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name)
{
    if (!obj) return;

    QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0;

    QStringList path = name.split(QLatin1Char('.'));
    if (path.isEmpty()) return;

    QObject *currentObject = obj;

    // Everything up to the last property must be an "object type" property
    for (int ii = 0; ii < path.count() - 1; ++ii) {
        const QString &pathName = path.at(ii);

        if (QDeclarativeTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) {
            if (data->type) {
                QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
                if (!func) return; // Not an attachable type

                currentObject = qmlAttachedPropertiesObjectById(data->type->attachedPropertiesId(), currentObject);
                if (!currentObject) return; // Something is broken with the attachable type
            } else {
                Q_ASSERT(data->typeNamespace);
                if ((ii + 1) == path.count()) return; // No type following the namespace
                
                ++ii; data = data->typeNamespace->data(path.at(ii));
                if (!data || !data->type) return; // Invalid type in namespace 

                QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction();
                if (!func) return; // Not an attachable type

                currentObject = qmlAttachedPropertiesObjectById(data->type->attachedPropertiesId(), currentObject);
                if (!currentObject) return; // Something is broken with the attachable type
            }
        } else {

            QDeclarativePropertyCache::Data local;
            QDeclarativePropertyCache::Data *property = 
                QDeclarativePropertyCache::property(engine, obj, pathName, local);

            if (!property) return; // Not a property
            if (property->flags & QDeclarativePropertyCache::Data::IsFunction) 
                return; // Not an object property 

            if (ii == (path.count() - 2) && QDeclarativeValueTypeFactory::isValueType(property->propType)) {
                // We're now at a value type property.  We can use a global valuetypes array as we 
                // never actually use the objects, just look up their properties.
                QObject *typeObject = (*qmlValueTypes())[property->propType];
                if (!typeObject) return; // Not a value type

                int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData());
                if (idx == -1) return; // Value type property does not exist

                QMetaProperty vtProp = typeObject->metaObject()->property(idx);

                object = currentObject;
                core = *property;
                valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(vtProp);
                valueType.valueTypeCoreIdx = idx;
                valueType.valueTypePropType = vtProp.userType();

                return; 
            } else {
                if (!(property->flags & QDeclarativePropertyCache::Data::IsQObjectDerived)) 
                    return; // Not an object property

                void *args[] = { &currentObject, 0 };
                QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args);
                if (!currentObject) return; // No value

            }
        }

    }

    const QString &terminal = path.last();

    if (terminal.count() >= 3 &&
        terminal.at(0) == QLatin1Char('o') &&
        terminal.at(1) == QLatin1Char('n') &&
        terminal.at(2).isUpper()) {

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

        QMetaMethod method = findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
        if (method.signature()) {
            object = currentObject;
            core.load(method);
            return;
        }
    }

    // Property
    QDeclarativePropertyCache::Data local;
    QDeclarativePropertyCache::Data *property = 
        QDeclarativePropertyCache::property(engine, currentObject, terminal, local);
    if (property && !(property->flags & QDeclarativePropertyCache::Data::IsFunction)) {
        object = currentObject;
        core = *property;
        nameCache = terminal;
        isNameCached = true;
    }
}

/*!
    Create a copy of \a other.
*/
QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other)
{
    d = other.d;
    if (d)
        d->addref();
}

/*!
  \enum QDeclarativeProperty::PropertyTypeCategory

  This enum specifies a category of QML property.

  \value InvalidCategory The property is invalid, or is a signal property.
  \value List The property is a QDeclarativeListProperty list property
  \value Object The property is a QObject derived type pointer
  \value Normal The property is a normal value property.
 */

/*!
  \enum QDeclarativeProperty::Type

  This enum specifies a type of QML property.

  \value Invalid The property is invalid.
  \value Property The property is a regular Qt property.
  \value SignalProperty The property is a signal property.
*/

/*!
    Returns the property category.
*/
QDeclarativeProperty::PropertyTypeCategory QDeclarativeProperty::propertyTypeCategory() const
{
    return d ? d->propertyTypeCategory() : InvalidCategory;
}

QDeclarativeProperty::PropertyTypeCategory 
QDeclarativePropertyPrivate::propertyTypeCategory() const
{
    uint type = this->type();

    if (isValueType()) {
        return QDeclarativeProperty::Normal;
    } else if (type & QDeclarativeProperty::Property) {
        int type = propertyType();
        if (type == QVariant::Invalid)
            return QDeclarativeProperty::InvalidCategory;
        else if (QDeclarativeValueTypeFactory::isValueType((uint)type))
            return QDeclarativeProperty::Normal;
        else if (core.flags & QDeclarativePropertyCache::Data::IsQObjectDerived)
            return QDeclarativeProperty::Object;
        else if (core.flags & QDeclarativePropertyCache::Data::IsQList)
            return QDeclarativeProperty::List;
        else 
            return QDeclarativeProperty::Normal;
    } else {
        return QDeclarativeProperty::InvalidCategory;
    }
}

/*!
    Returns the type name of the property, or 0 if the property has no type
    name.
*/
const char *QDeclarativeProperty::propertyTypeName() const
{
    if (!d)
        return 0;
    if (d->isValueType()) {

        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context);
        QDeclarativeValueType *valueType = 0;
        if (ep) valueType = ep->valueTypes[d->core.propType];
        else valueType = QDeclarativeValueTypeFactory::valueType(d->core.propType);
        Q_ASSERT(valueType);

        const char *rv = valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).typeName();

        if (!ep) delete valueType;

        return rv;
    } else if (d->object && type() & Property && d->core.isValid()) {
        return d->object->metaObject()->property(d->core.coreIndex).typeName();
    } else {
        return 0;
    }
}

/*!
    Returns true if \a other and this QDeclarativeProperty represent the same 
    property.
*/
bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
{
    if (!d || !other.d)
        return false;
    // category is intentially omitted here as it is generated 
    // from the other members
    return d->object == other.d->object &&
           d->core == other.d->core &&
           d->valueType == other.d->valueType;
}

/*!
    Returns the QVariant type of the property, or QVariant::Invalid if the 
    property has no QVariant type.
*/
int QDeclarativeProperty::propertyType() const
{
    return d ? d->propertyType() : int(QVariant::Invalid);
}

bool QDeclarativePropertyPrivate::isValueType() const
{
    return valueType.valueTypeCoreIdx != -1;
}

int QDeclarativePropertyPrivate::propertyType() const
{
    uint type = this->type();
    if (isValueType()) {
        return valueType.valueTypePropType;
    } else if (type & QDeclarativeProperty::Property) {
        if (core.propType == (int)QVariant::LastType)
            return qMetaTypeId<QVariant>();
        else
            return core.propType;
    } else {
        return QVariant::Invalid;
    }
}

QDeclarativeProperty::Type QDeclarativePropertyPrivate::type() const
{
    if (core.flags & QDeclarativePropertyCache::Data::IsFunction)
        return QDeclarativeProperty::SignalProperty;
    else if (core.isValid())
        return QDeclarativeProperty::Property;
    else
        return QDeclarativeProperty::Invalid;
}

/*!
    Returns the type of the property.
*/
QDeclarativeProperty::Type QDeclarativeProperty::type() const
{
    return d ? d->type() : Invalid;
}

/*!
    Returns true if this QDeclarativeProperty represents a regular Qt property.
*/
bool QDeclarativeProperty::isProperty() const
{
    return type() & Property;
}

/*!
    Returns true if this QDeclarativeProperty represents a QML signal property.
*/
bool QDeclarativeProperty::isSignalProperty() const
{
    return type() & SignalProperty;
}

/*!
    Returns the QDeclarativeProperty's QObject.
*/
QObject *QDeclarativeProperty::object() const
{
    return d ? d->object : 0;
}

/*!
    Assign \a other to this QDeclarativeProperty.
*/
QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty &other)
{
    if (d)
        d->release();
    d = other.d;
    if (d)
        d->addref();

    return *this;
}

/*!
    Returns true if the property is writable, otherwise false.
*/
bool QDeclarativeProperty::isWritable() const
{
    if (!d)
        return false;
    if (!d->object)
        return false;
    if (d->core.flags & QDeclarativePropertyCache::Data::IsQList)           //list
        return true;
    else if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction)   //signal handler
        return false;
    else if (d->core.isValid())                                             //normal property
        return d->core.flags & QDeclarativePropertyCache::Data::IsWritable;
    else
        return false;
}

/*!
    Returns true if the property is designable, otherwise false.
*/
bool QDeclarativeProperty::isDesignable() const
{
    if (!d)
        return false;
    if (type() & Property && d->core.isValid() && d->object)
        return d->object->metaObject()->property(d->core.coreIndex).isDesignable();
    else
        return false;
}

/*!
    Returns true if the property is resettable, otherwise false.
*/
bool QDeclarativeProperty::isResettable() const
{
    if (!d)
        return false;
    if (type() & Property && d->core.isValid() && d->object)
        return d->core.flags & QDeclarativePropertyCache::Data::IsResettable;
    else
        return false;
}

/*!
    Returns true if the QDeclarativeProperty refers to a valid property, otherwise
    false.
*/
bool QDeclarativeProperty::isValid() const
{
    if (!d)
        return false;
    return type() != Invalid;
}

/*!
    Return the name of this QML property.
*/
QString QDeclarativeProperty::name() const
{
    if (!d)
        return QString();
    if (!d->isNameCached) {
        // ###
        if (!d->object) {
        } else if (d->isValueType()) {
            QString rv = d->core.name(d->object) + QLatin1Char('.');

            QDeclarativeEnginePrivate *ep = d->engine?QDeclarativeEnginePrivate::get(d->engine):0;
            QDeclarativeValueType *valueType = 0;
            if (ep) valueType = ep->valueTypes[d->core.propType];
            else valueType = QDeclarativeValueTypeFactory::valueType(d->core.propType);
            Q_ASSERT(valueType);

            rv += QString::fromUtf8(valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).name());

            if (!ep) delete valueType;

            d->nameCache = rv;
        } else if (type() & SignalProperty) {
            QString name = QLatin1String("on") + d->core.name(d->object);
            name[2] = name.at(2).toUpper();
            d->nameCache = name;
        } else {
            d->nameCache = d->core.name(d->object);
        }
        d->isNameCached = true;
    }

    return d->nameCache;
}

/*!
  Returns the \l{QMetaProperty} {Qt property} associated with
  this QML property.
 */
QMetaProperty QDeclarativeProperty::property() const
{
    if (!d)
        return QMetaProperty();
    if (type() & Property && d->core.isValid() && d->object)
        return d->object->metaObject()->property(d->core.coreIndex);
    else
        return QMetaProperty();
}

/*!
    Return the QMetaMethod for this property if it is a SignalProperty, 
    otherwise returns an invalid QMetaMethod.
*/
QMetaMethod QDeclarativeProperty::method() const
{
    if (!d)
        return QMetaMethod();
    if (type() & SignalProperty && d->object)
        return d->object->metaObject()->method(d->core.coreIndex);
    else
        return QMetaMethod();
}

/*!
    Returns the binding associated with this property, or 0 if no binding 
    exists.
*/
QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that) 
{
    if (!that.d || !that.isProperty() || !that.d->object)
        return 0;

    return binding(that.d->object, that.d->core.coreIndex, that.d->valueType.valueTypeCoreIdx);
}

/*!
    Set the binding associated with this property to \a newBinding.  Returns
    the existing binding (if any), otherwise 0.

    \a newBinding will be enabled, and the returned binding (if any) will be
    disabled.

    Ownership of \a newBinding transfers to QML.  Ownership of the return value
    is assumed by the caller.

    \a flags is passed through to the binding and is used for the initial update (when
    the binding sets the initial value, it will use these flags for the write).
*/
QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
                                            QDeclarativeAbstractBinding *newBinding, 
                                            WriteFlags flags) 
{
    if (!that.d || !that.isProperty() || !that.d->object) {
        if (newBinding)
            newBinding->destroy();
        return 0;
    }

    return that.d->setBinding(that.d->object, that.d->core.coreIndex, 
                              that.d->valueType.valueTypeCoreIdx, newBinding, flags);
}

QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
{
    QDeclarativeData *data = QDeclarativeData::get(object);
    if (!data)
        return 0;

    QDeclarativePropertyCache::Data *propertyData = 
        data->propertyCache?data->propertyCache->property(coreIndex):0;
    if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) {
        const QDeclarativeVMEMetaObject *vme = 
            static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));

        QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
        if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex) || aCoreIndex == -1)
            return 0;

        // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
        Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
        return binding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex);
    }

    if (!data->hasBindingBit(coreIndex))
        return 0;

    QDeclarativeAbstractBinding *binding = data->bindings;
    while (binding && binding->propertyIndex() != coreIndex)
        binding = binding->m_nextBinding;

    if (binding && valueTypeIndex != -1) {
        if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
            int index = coreIndex | (valueTypeIndex << 24);
            binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
        }
    }

    return binding;
}

void QDeclarativePropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, 
                                                  QObject **targetObject, int *targetBindingIndex)
{
    int coreIndex = bindingIndex & 0xFFFFFF;
    int valueTypeIndex = bindingIndex >> 24;
    if (valueTypeIndex == 0) valueTypeIndex = -1;

    QDeclarativeData *data = QDeclarativeData::get(object, false);
    if (data) {
        QDeclarativePropertyCache::Data *propertyData = 
            data->propertyCache?data->propertyCache->property(coreIndex):0;
        if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) {
            const QDeclarativeVMEMetaObject *vme = 
                static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
            QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
            if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
                // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
                Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);

                int aBindingIndex = aCoreIndex;
                if (aValueTypeIndex != -1) 
                    aBindingIndex |= aValueTypeIndex << 24;
                else if (valueTypeIndex != -1)
                    aBindingIndex |= valueTypeIndex << 24;

                findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex);
                return;
            }
        }
    }

    *targetObject = object; 
    *targetBindingIndex = bindingIndex;
}

QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex,
                                        QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
{
    QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding);
    QDeclarativeAbstractBinding *binding = 0;

    if (data) {
        QDeclarativePropertyCache::Data *propertyData = 
            data->propertyCache?data->propertyCache->property(coreIndex):0;
        if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) {
            const QDeclarativeVMEMetaObject *vme = 
                static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));

            QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
            if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
                if (newBinding) newBinding->destroy();
                return 0;
            }

            // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
            Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
            return setBinding(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex,
                              newBinding, flags);
        }
    }

    if (data && data->hasBindingBit(coreIndex)) {
        binding = data->bindings;

        while (binding && binding->propertyIndex() != coreIndex) 
            binding = binding->m_nextBinding;
    }

    int index = coreIndex;
    if (valueTypeIndex != -1)
        index |= (valueTypeIndex << 24);

    if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) 
        binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);

    if (binding) {
        binding->removeFromObject();
        binding->setEnabled(false, 0);
    }

    if (newBinding) {
        newBinding->addToObject(object, index);
        newBinding->setEnabled(true, flags);
    }

    return binding;
}

QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex,
                                                QDeclarativeAbstractBinding *newBinding)
{
    QDeclarativeData *data = QDeclarativeData::get(object, 0 != newBinding);
    QDeclarativeAbstractBinding *binding = 0;

    if (data) {
        QDeclarativePropertyCache::Data *propertyData = 
            data->propertyCache?data->propertyCache->property(coreIndex):0;
        if (propertyData && propertyData->flags & QDeclarativePropertyCache::Data::IsAlias) {
            const QDeclarativeVMEMetaObject *vme = 
                static_cast<const QDeclarativeVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));

            QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
            if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
                if (newBinding) newBinding->destroy();
                return 0;
            }

            // This will either be a value type sub-reference or an alias to a value-type sub-reference not both
            Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1);
            return setBindingNoEnable(aObject, aCoreIndex, (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex,
                                      newBinding);
        }
    }

    if (data && data->hasBindingBit(coreIndex)) {
        binding = data->bindings;

        while (binding && binding->propertyIndex() != coreIndex) 
            binding = binding->m_nextBinding;
    }

    int index = coreIndex;
    if (valueTypeIndex != -1)
        index |= (valueTypeIndex << 24);

    if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) 
        binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);

    if (binding) 
        binding->removeFromObject();

    if (newBinding) 
        newBinding->addToObject(object, index);

    return binding;
}

/*!
    Returns the expression associated with this signal property, or 0 if no 
    signal expression exists.
*/
QDeclarativeExpression *
QDeclarativePropertyPrivate::signalExpression(const QDeclarativeProperty &that)
{
    if (!(that.type() & QDeclarativeProperty::SignalProperty))
        return 0;

    const QObjectList &children = that.d->object->children();
    
    for (int ii = 0; ii < children.count(); ++ii) {
        QObject *child = children.at(ii);

        QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child);
        if (signal && signal->index() == that.index()) 
            return signal->expression();
    }

    return 0;
}

/*!
    Set the signal expression associated with this signal property to \a expr.
    Returns the existing signal expression (if any), otherwise 0.

    Ownership of \a expr transfers to QML.  Ownership of the return value is
    assumed by the caller.
*/
QDeclarativeExpression *
QDeclarativePropertyPrivate::setSignalExpression(const QDeclarativeProperty &that,
                                                     QDeclarativeExpression *expr) 
{
    if (!(that.type() & QDeclarativeProperty::SignalProperty)) {
        delete expr;
        return 0;
    }

    const QObjectList &children = that.d->object->children();
    
    for (int ii = 0; ii < children.count(); ++ii) {
        QObject *child = children.at(ii);

        QDeclarativeBoundSignal *signal = QDeclarativeBoundSignal::cast(child);
        if (signal && signal->index() == that.index()) 
            return signal->setExpression(expr);
    }

    if (expr) {
        QDeclarativeBoundSignal *signal = new QDeclarativeBoundSignal(that.d->object, that.method(), that.d->object);
        return signal->setExpression(expr);
    } else {
        return 0;
    }
}

/*!
    Returns the property value.
*/
QVariant QDeclarativeProperty::read() const
{
    if (!d)
        return QVariant();
    if (!d->object)
        return QVariant();

    if (type() & SignalProperty) {

        return QVariant();

    } else if (type() & Property) {

        return d->readValueProperty();

    }
    return QVariant();
}

/*!
Return the \a name property value of \a object.  This method is equivalent to:
\code
    QDeclarativeProperty p(object, name);
    p.read();
\endcode
*/
QVariant QDeclarativeProperty::read(QObject *object, const QString &name)
{
    QDeclarativeProperty p(object, name);
    return p.read();
}

/*!
  Return the \a name property value of \a object using the
  \l{QDeclarativeContext} {context} \a ctxt.  This method is
  equivalent to:

  \code
    QDeclarativeProperty p(object, name, context);
    p.read();
  \endcode
*/
QVariant QDeclarativeProperty::read(QObject *object, const QString &name, QDeclarativeContext *ctxt)
{
    QDeclarativeProperty p(object, name, ctxt);
    return p.read();
}

/*!
  
  Return the \a name property value of \a object using the environment
  for instantiating QML components that is provided by \a engine. .
  This method is equivalent to:

  \code
    QDeclarativeProperty p(object, name, engine);
    p.read();
  \endcode
*/
QVariant QDeclarativeProperty::read(QObject *object, const QString &name, QDeclarativeEngine *engine)
{
    QDeclarativeProperty p(object, name, engine);
    return p.read();
}

QVariant QDeclarativePropertyPrivate::readValueProperty()
{
    if (isValueType()) {

        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context);
        QDeclarativeValueType *valueType = 0;
        if (ep) valueType = ep->valueTypes[core.propType];
        else valueType = QDeclarativeValueTypeFactory::valueType(core.propType);
        Q_ASSERT(valueType);

        valueType->read(object, core.coreIndex);

        QVariant rv =
            valueType->metaObject()->property(this->valueType.valueTypeCoreIdx).read(valueType);

        if (!ep) delete valueType;
        return rv;

    } else if (core.flags & QDeclarativePropertyCache::Data::IsQList) {

        QDeclarativeListProperty<QObject> prop;
        void *args[] = { &prop, 0 };
        QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
        return QVariant::fromValue(QDeclarativeListReferencePrivate::init(prop, core.propType, engine)); 

    } else if (core.flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {

        QObject *rv = 0;
        void *args[] = { &rv, 0 };
        QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
        return QVariant::fromValue(rv);

    } else {

        return object->metaObject()->property(core.coreIndex).read(object.data());

    }
}

//writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC!
bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags)
{
    if (!object || !prop.isWritable())
        return false;

    QVariant v = value;
    if (prop.isEnumType()) {
        QMetaEnum menum = prop.enumerator();
        if (v.userType() == QVariant::String
#ifdef QT3_SUPPORT
            || v.userType() == QVariant::CString
#endif
            ) {
            if (prop.isFlagType())
                v = QVariant(menum.keysToValue(value.toByteArray()));
            else
                v = QVariant(menum.keyToValue(value.toByteArray()));
        } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
            int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope()) + "::" + menum.name());
            if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())
                return false;
            v = QVariant(*reinterpret_cast<const int *>(v.constData()));
        }
        v.convert(QVariant::Int);
    }

    // the status variable is changed by qt_metacall to indicate what it did
    // this feature is currently only used by QtDBus and should not be depended
    // upon. Don't change it without looking into QDBusAbstractInterface first
    // -1 (unchanged): normal qt_metacall, result stored in argv[0]
    // changed: result stored directly in value, return the value of status
    int status = -1;
    void *argv[] = { v.data(), &v, &status, &flags };
    QMetaObject::metacall(object, QMetaObject::WriteProperty, idx, argv);
    return status;
}

bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, WriteFlags flags)
{
    // Remove any existing bindings on this property
    if (!(flags & DontRemoveBinding) &&
        (type() & QDeclarativeProperty::Property) && object) {
        QDeclarativeAbstractBinding *binding = setBinding(object, core.coreIndex,
                                                          valueType.valueTypeCoreIdx, 0, flags);
        if (binding) binding->destroy();
    }

    bool rv = false;
    if (isValueType()) {
        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context);

        QDeclarativeValueType *writeBack = 0;
        if (ep) {
            writeBack = ep->valueTypes[core.propType];
        } else {
            writeBack = QDeclarativeValueTypeFactory::valueType(core.propType);
        }

        writeBack->read(object, core.coreIndex);

        QDeclarativePropertyCache::Data data = core;
        data.flags = valueType.flags;
        data.coreIndex = valueType.valueTypeCoreIdx;
        data.propType = valueType.valueTypePropType;
        rv = write(writeBack, data, value, context, flags);

        writeBack->write(object, core.coreIndex, flags);
        if (!ep) delete writeBack;

    } else {

        rv = write(object, core, value, context, flags);

    }

    return rv;
}

bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property, 
                                            const QVariant &value, QDeclarativeContextData *context, 
                                            WriteFlags flags)
{
    int coreIdx = property.coreIndex;
    int status = -1;    //for dbus

    if (property.flags & QDeclarativePropertyCache::Data::IsEnumType) {
        QMetaProperty prop = object->metaObject()->property(property.coreIndex);
        QVariant v = value;
        // Enum values come through the script engine as doubles
        if (value.userType() == QVariant::Double) { 
            double integral;
            double fractional = modf(value.toDouble(), &integral);
            if (qFuzzyIsNull(fractional))
                v.convert(QVariant::Int);
        }
        return writeEnumProperty(prop, coreIdx, object, v, flags);
    }

    int propertyType = property.propType;
    int variantType = value.userType();

    QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context);

    if (propertyType == QVariant::Url) {

        QUrl u;
        bool found = false;
        if (variantType == QVariant::Url) {
            u = value.toUrl();
            found = true;
        } else if (variantType == QVariant::ByteArray) {
            u = QUrl(QString::fromUtf8(value.toByteArray()));
            found = true;
        } else if (variantType == QVariant::String) {
            u = QUrl(value.toString());
            found = true;
        }

        if (!found)
            return false;

        if (context && u.isRelative() && !u.isEmpty())
            u = context->resolvedUrl(u);
        int status = -1;
        void *argv[] = { &u, 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, argv);

    } else if (variantType == propertyType) {

        void *a[] = { (void *)value.constData(), 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);

    } else if (qMetaTypeId<QVariant>() == propertyType) {

        void *a[] = { (void *)&value, 0, &status, &flags };
        QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);

    } else if (property.flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {

        const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType());
        
        if (!valMo)
            return false;

        QObject *o = *(QObject **)value.constData();
        const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType);

        if (o) valMo = o->metaObject();

        if (canConvert(valMo, propMo)) {
            void *args[] = { &o, 0, &status, &flags };
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, 
                                  args);
        } else if (!o && canConvert(propMo, valMo)) {
            // In the case of a null QObject, we assign the null if there is 
            // any change that the null variant type could be up or down cast to 
            // the property type.
            void *args[] = { &o, 0, &status, &flags };
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, 
                                  args);
        } else {
            return false;
        }

    } else if (property.flags & QDeclarativePropertyCache::Data::IsQList) {

        const QMetaObject *listType = 0;
        if (enginePriv) {
            listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
        } else {
            QDeclarativeType *type = QDeclarativeMetaType::qmlType(QDeclarativeMetaType::listType(property.propType));
            if (!type) return false;
            listType = type->baseMetaObject();
        }
        if (!listType) return false;

        QDeclarativeListProperty<void> prop;
        void *args[] = { &prop, 0 };
        QMetaObject::metacall(object, QMetaObject::ReadProperty, coreIdx, args);

        if (!prop.clear) return false;

        prop.clear(&prop);

        if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
            const QList<QObject *> &list = qvariant_cast<QList<QObject *> >(value);

            for (int ii = 0; ii < list.count(); ++ii) {
                QObject *o = list.at(ii);
                if (o && !canConvert(o->metaObject(), listType))
                    o = 0;
                prop.append(&prop, (void *)o);
            }
        } else {
            QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value);
            if (o && !canConvert(o->metaObject(), listType))
                o = 0;
            prop.append(&prop, (void *)o);
        }

    } else {
        Q_ASSERT(variantType != propertyType);

        bool ok = false;
        QVariant v;
        if (variantType == QVariant::String)
            v = QDeclarativeStringConverters::variantFromString(value.toString(), propertyType, &ok);
        if (!ok) {
            v = value;
            if (v.convert((QVariant::Type)propertyType)) {
                ok = true;
            } else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) {
                QDeclarativeMetaType::StringConverter con = QDeclarativeMetaType::customStringConverter(propertyType);
                if (con) {
                    v = con(value.toString());
                    if (v.userType() == propertyType)
                        ok = true;
                }
            }
        }
        if (ok) {
            void *a[] = { (void *)v.constData(), 0, &status, &flags};
            QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
        } else {
            return false;
        }
    }

    return true;
}

const QMetaObject *QDeclarativePropertyPrivate::rawMetaObjectForType(QDeclarativeEnginePrivate *engine, int userType)
{
    if (engine) {
        return engine->rawMetaObjectForType(userType);
    } else {
        QDeclarativeType *type = QDeclarativeMetaType::qmlType(userType);
        return type?type->baseMetaObject():0;
    }
}

/*!
    Sets the property value to \a value and returns true.
    Returns false if the property can't be set because the
    \a value is the wrong type, for example.
 */
bool QDeclarativeProperty::write(const QVariant &value) const
{
    return QDeclarativePropertyPrivate::write(*this, value, 0);
}

/*!
  Writes \a value to the \a name property of \a object.  This method
  is equivalent to:

  \code
    QDeclarativeProperty p(object, name);
    p.write(value);
  \endcode
*/
bool QDeclarativeProperty::write(QObject *object, const QString &name, const QVariant &value)
{
    QDeclarativeProperty p(object, name);
    return p.write(value);
}

/*!
  Writes \a value to the \a name property of \a object using the
  \l{QDeclarativeContext} {context} \a ctxt.  This method is
  equivalent to:

  \code
    QDeclarativeProperty p(object, name, ctxt);
    p.write(value);
  \endcode
*/
bool QDeclarativeProperty::write(QObject *object,
                                 const QString &name,
                                 const QVariant &value, 
                                 QDeclarativeContext *ctxt)
{
    QDeclarativeProperty p(object, name, ctxt);
    return p.write(value);
}

/*!
  
  Writes \a value to the \a name property of \a object using the
  environment for instantiating QML components that is provided by
  \a engine.  This method is equivalent to:

  \code
    QDeclarativeProperty p(object, name, engine);
    p.write(value);
  \endcode
*/
bool QDeclarativeProperty::write(QObject *object, const QString &name, const QVariant &value, 
                                 QDeclarativeEngine *engine)
{
    QDeclarativeProperty p(object, name, engine);
    return p.write(value);
}

/*!
    Resets the property and returns true if the property is
    resettable.  If the property is not resettable, nothing happens
    and false is returned.
*/
bool QDeclarativeProperty::reset() const
{
    if (isResettable()) {
        void *args[] = { 0 };
        QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex, args);
        return true;
    } else {
        return false;
    }
}

bool QDeclarativePropertyPrivate::write(const QDeclarativeProperty &that,
                                            const QVariant &value, WriteFlags flags) 
{
    if (!that.d)
        return false;
    if (that.d->object && that.type() & QDeclarativeProperty::Property && 
        that.d->core.isValid() && that.isWritable()) 
        return that.d->writeValueProperty(value, flags);
    else 
        return false;
}

/*!
    Returns true if the property has a change notifier signal, otherwise false.
*/
bool QDeclarativeProperty::hasNotifySignal() const
{
    if (type() & Property && d->object) {
        return d->object->metaObject()->property(d->core.coreIndex).hasNotifySignal();
    }
    return false;
}

/*!
    Returns true if the property needs a change notifier signal for bindings
    to remain upto date, false otherwise.

    Some properties, such as attached properties or those whose value never 
    changes, do not require a change notifier.
*/
bool QDeclarativeProperty::needsNotifySignal() const
{
    return type() & Property && !property().isConstant();
}

/*!
    Connects the property's change notifier signal to the
    specified \a method of the \a dest object and returns
    true. Returns false if this metaproperty does not
    represent a regular Qt property or if it has no
    change notifier signal, or if the \a dest object does
    not have the specified \a method.
*/
bool QDeclarativeProperty::connectNotifySignal(QObject *dest, int method) const
{
    if (!(type() & Property) || !d->object)
        return false;

    QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex);
    if (prop.hasNotifySignal()) {
        return QDeclarativePropertyPrivate::connect(d->object, prop.notifySignalIndex(), dest, method, Qt::DirectConnection);
    } else {
        return false;
    }
}

/*!
    Connects the property's change notifier signal to the
    specified \a slot of the \a dest object and returns
    true. Returns false if this metaproperty does not
    represent a regular Qt property or if it has no
    change notifier signal, or if the \a dest object does
    not have the specified \a slot.
*/
bool QDeclarativeProperty::connectNotifySignal(QObject *dest, const char *slot) const
{
    if (!(type() & Property) || !d->object)
        return false;

    QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex);
    if (prop.hasNotifySignal()) {
        QByteArray signal(QByteArray("2") + prop.notifySignal().signature());
        return QObject::connect(d->object, signal.constData(), dest, slot);
    } else  {
        return false;
    }
}

/*!
    Return the Qt metaobject index of the property.
*/
int QDeclarativeProperty::index() const
{
    return d ? d->core.coreIndex : -1;
}

int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &that)
{
    return that.d ? that.d->valueType.valueTypeCoreIdx : -1;
}

/*!
    Returns the "property index" for use in bindings.  The top 8 bits are the value type
    offset, and 0 otherwise.  The bottom 24-bits are the regular property index.
*/
int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
{
    if (!that.d)
        return -1;
    int rv = that.d->core.coreIndex;
    if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1)
        rv = rv | (that.d->valueType.valueTypeCoreIdx << 24);
    return rv;
}

struct SerializedData {
    bool isValueType;
    QDeclarativePropertyCache::Data core;
};

struct ValueTypeSerializedData : public SerializedData {
    QDeclarativePropertyCache::ValueTypeData valueType;
};

QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObject, int index, 
                                                 const QMetaObject *subObject, int subIndex)
{
    QMetaProperty prop = metaObject->property(index);
    QMetaProperty subProp = subObject->property(subIndex);

    ValueTypeSerializedData sd;
    memset(&sd, 0, sizeof(sd));
    sd.isValueType = true;
    sd.core.load(metaObject->property(index));
    sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp);
    sd.valueType.valueTypeCoreIdx = subIndex;
    sd.valueType.valueTypePropType = subProp.userType();

    QByteArray rv((const char *)&sd, sizeof(sd));

    return rv;
}

QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index)
{
    SerializedData sd;
    memset(&sd, 0, sizeof(sd));
    sd.isValueType = false;
    sd.core.load(metaObject->property(index));

    QByteArray rv((const char *)&sd, sizeof(sd));
    return rv;
}

QDeclarativeProperty 
QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt)
{
    QDeclarativeProperty prop;

    if (data.isEmpty())
        return prop;

    const SerializedData *sd = (const SerializedData *)data.constData();
    if (sd->isValueType) {
        const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd;
        return restore(vt->core, vt->valueType, object, ctxt);
    } else {
        QDeclarativePropertyCache::ValueTypeData data;
        return restore(sd->core, data, object, ctxt);
    }
}

QDeclarativeProperty
QDeclarativePropertyPrivate::restore(const QDeclarativePropertyCache::Data &data, const QDeclarativePropertyCache::ValueTypeData &valueType, QObject *object, QDeclarativeContextData *ctxt)
{
    QDeclarativeProperty prop;

    prop.d = new QDeclarativePropertyPrivate;
    prop.d->object = object;
    prop.d->context = ctxt;
    prop.d->engine = ctxt->engine;

    prop.d->core = data;
    prop.d->valueType = valueType;

    return prop;
}

/*!
    Returns true if lhs and rhs refer to the same metaobject data
*/
bool QDeclarativePropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rhs)
{
    return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
}

/*!
    Returns true if from inherits to.
*/
bool QDeclarativePropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to)
{
    if (from && to == &QObject::staticMetaObject)
        return true;

    while (from) {
        if (equal(from, to))
            return true;
        from = from->superClass();
    }
    
    return false;
}

/*!
    Return the signal corresponding to \a name
*/
QMetaMethod QDeclarativePropertyPrivate::findSignalByName(const QMetaObject *mo, const QByteArray &name)
{
    Q_ASSERT(mo);
    int methods = mo->methodCount();
    for (int ii = methods - 1; ii >= 2; --ii) { // >= 2 to block the destroyed signal
        QMetaMethod method = mo->method(ii);
        QByteArray methodName = method.signature();
        int idx = methodName.indexOf('(');
        methodName = methodName.left(idx);

        if (methodName == name)
            return method;
    }

    // If no signal is found, but the signal is of the form "onBlahChanged",
    // return the notify signal for the property "Blah"
    if (name.endsWith("Changed")) {
        QByteArray propName = name.mid(0, name.length() - 7);
        int propIdx = mo->indexOfProperty(propName.constData());
        if (propIdx >= 0) {
            QMetaProperty prop = mo->property(propIdx);
            if (prop.hasNotifySignal())
                return prop.notifySignal();
        }
    }

    return QMetaMethod();
}

static inline int QMetaObject_methods(const QMetaObject *metaObject)
{
    struct Private
    {
        int revision;
        int className;
        int classInfoCount, classInfoData;
        int methodCount, methodData;
        int propertyCount, propertyData;
    };

    return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
}

static inline int QMetaObject_properties(const QMetaObject *metaObject)
{
    struct Private
    {
        int revision;
        int className;
        int classInfoCount, classInfoData;
        int methodCount, methodData;
        int propertyCount, propertyData;
    };

    return reinterpret_cast<const Private *>(metaObject->d.data)->propertyCount;
}

static inline void flush_vme_signal(const QObject *object, int index)
{
    QDeclarativeData *data = static_cast<QDeclarativeData *>(QObjectPrivate::get(const_cast<QObject *>(object))->declarativeData);
    if (data && data->propertyCache) {
        QDeclarativePropertyCache::Data *property = data->propertyCache->method(index);

        if (property && property->flags & QDeclarativePropertyCache::Data::IsVMESignal) {
            const QMetaObject *metaObject = object->metaObject();
            int methodOffset = metaObject->methodOffset();

            while (methodOffset > index) {
                metaObject = metaObject->d.superdata;
                methodOffset -= QMetaObject_methods(metaObject);
            }

            QDeclarativeVMEMetaObject *vme = 
                static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(metaObject));

            vme->connectAliasSignal(index);
        }
    }
}

/*!
Connect \a sender \a signal_index to \a receiver \a method_index with the specified 
\a type and \a types.  This behaves identically to QMetaObject::connect() except that
it connects any lazy "proxy" signal connections set up by QML.

It is possible that this logic should be moved to QMetaObject::connect().
*/
bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_index,
                                          const QObject *receiver, int method_index,
                                          int type, int *types)
{
    flush_vme_signal(sender, signal_index);
    flush_vme_signal(receiver, method_index);

    return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
}

/*!
Return \a metaObject's [super] meta object that provides data for \a property.
*/
const QMetaObject *QDeclarativePropertyPrivate::metaObjectForProperty(const QMetaObject *metaObject, int property)
{
    int propertyOffset = metaObject->propertyOffset();

    while (propertyOffset > property) {
        metaObject = metaObject->d.superdata;
        propertyOffset -= QMetaObject_properties(metaObject);
    }

    return metaObject;
}

QT_END_NAMESPACE
