void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier &,
                                                   const QScriptValue &value)
{
    QDeclarativeValueTypeObject *o = static_cast<QDeclarativeValueTypeObject *>(obj);

    QVariant v = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value);

    if (o->objectType == QDeclarativeValueTypeObject::Reference) {
        QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);

        ref->type->read(ref->object, ref->property);
        QMetaProperty p = ref->type->metaObject()->property(m_lastIndex);

        QDeclarativeBinding *newBinding = 0;
        if (value.isFunction() && !value.isRegExp()) {
            QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(engine)->getContext(context());

            QDeclarativePropertyCache::Data cacheData;
            cacheData.flags = QDeclarativePropertyCache::Data::IsWritable;
            cacheData.propType = ref->object->metaObject()->property(ref->property).userType();
            cacheData.coreIndex = ref->property;

            QDeclarativePropertyCache::ValueTypeData valueTypeData;
            valueTypeData.valueTypeCoreIdx = m_lastIndex;
            valueTypeData.valueTypePropType = p.userType();

            newBinding = new QDeclarativeBinding(value, ref->object, ctxt);
            QScriptContextInfo ctxtInfo(context());
            newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
            QDeclarativeProperty prop = QDeclarativePropertyPrivate::restore(cacheData, valueTypeData, ref->object, ctxt);
            newBinding->setTarget(prop);
            if (newBinding->expression().contains(QLatin1String("this")))
                newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
        }

        QDeclarativeAbstractBinding *delBinding =
            QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, newBinding);
        if (delBinding)
            delBinding->destroy();

        if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
            v = v.toInt();
        p.write(ref->type, v);
        ref->type->write(ref->object, ref->property, 0);

    } else {
        QDeclarativeValueTypeCopy *copy = static_cast<QDeclarativeValueTypeCopy *>(obj);
        copy->type->setValue(copy->value);
        QMetaProperty p = copy->type->metaObject()->property(m_lastIndex);
        p.write(copy->type, v);
        copy->value = copy->type->value();
    }
}
void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
                                                const Identifier &name,
                                                const QScriptValue &value,
                                                QScriptContext *context,
                                                QDeclarativeContextData *evalContext)
{
    Q_UNUSED(name);

    Q_ASSERT(obj);
    Q_ASSERT(lastData);
    Q_ASSERT(context);

    if (!lastData->isValid()) {
        QString error = QLatin1String("Cannot assign to non-existent property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

    if (!(lastData->flags & QDeclarativePropertyCache::Data::IsWritable) && 
        !(lastData->flags & QDeclarativePropertyCache::Data::IsQList)) {
        QString error = QLatin1String("Cannot assign to read-only property \"") +
                        toString(name) + QLatin1Char('\"');
        context->throwError(error);
        return;
    }

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

    if (!evalContext) {
        // Global object, QScriptContext activation object, QDeclarativeContext object
        QScriptValue scopeNode = scopeChainValue(context, -3);
        if (scopeNode.isValid()) {
            Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);

            evalContext = enginePriv->contextClass->contextFromValue(scopeNode);
        }
    }

    QDeclarativeBinding *newBinding = 0;
    if (value.isFunction() && !value.isRegExp()) {
        QScriptContextInfo ctxtInfo(context);
        QDeclarativePropertyCache::ValueTypeData valueTypeData;

        newBinding = new QDeclarativeBinding(value, obj, evalContext);
        newBinding->setSourceLocation(ctxtInfo.fileName(), ctxtInfo.functionStartLineNumber());
        newBinding->setTarget(QDeclarativePropertyPrivate::restore(*lastData, valueTypeData, obj, evalContext));
        if (newBinding->expression().contains(QLatin1String("this")))
            newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
    }

    QDeclarativeAbstractBinding *delBinding =
        QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, newBinding);
    if (delBinding)
        delBinding->destroy();

    if (value.isNull() && lastData->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {
        QObject *o = 0;
        int status = -1;
        int flags = 0;
        void *argv[] = { &o, 0, &status, &flags };
        QMetaObject::metacall(obj, QMetaObject::WriteProperty, lastData->coreIndex, argv);
    } else if (value.isUndefined() && lastData->flags & QDeclarativePropertyCache::Data::IsResettable) {
        void *a[] = { 0 };
        QMetaObject::metacall(obj, QMetaObject::ResetProperty, lastData->coreIndex, a);
    } else if (value.isUndefined() && lastData->propType == qMetaTypeId<QVariant>()) {
        QDeclarativePropertyPrivate::write(obj, *lastData, QVariant(), evalContext);
    } else if (value.isUndefined()) {
        QString error = QLatin1String("Cannot assign [undefined] to ") +
                        QLatin1String(QMetaType::typeName(lastData->propType));
        context->throwError(error);
    } else if (value.isFunction() && !value.isRegExp()) {
        // this is handled by the binding creation above
    } else {
        //### expand optimization for other known types
        if (lastData->propType == QMetaType::Int && value.isNumber()) {
            int rawValue = qRoundDouble(value.toNumber());
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        } else if (lastData->propType == QMetaType::QReal && value.isNumber()) {
            qreal rawValue = qreal(value.toNumber());
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        } else if (lastData->propType == QMetaType::QString && value.isString()) {
            const QString &rawValue = value.toString();
            int status = -1;
            int flags = 0;
            void *a[] = { (void *)&rawValue, 0, &status, &flags };
            QMetaObject::metacall(obj, QMetaObject::WriteProperty,
                                  lastData->coreIndex, a);
            return;
        }

        QVariant v;
        if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
            v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
        else
            v = enginePriv->scriptValueToVariant(value, lastData->propType);

        if (!QDeclarativePropertyPrivate::write(obj, *lastData, v, evalContext)) {
            const char *valueType = 0;
            if (v.userType() == QVariant::Invalid) valueType = "null";
            else valueType = QMetaType::typeName(v.userType());

            QString error = QLatin1String("Cannot assign ") +
                            QLatin1String(valueType) +
                            QLatin1String(" to ") +
                            QLatin1String(QMetaType::typeName(lastData->propType));
            context->throwError(error);
        }
    }
}