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