// Variant value must be released with NPReleaseVariantValue()
void convertValueToNPVariant (KJS::ExecState *exec, const KJS::Value &value, NPVariant *result)
{
    Type type = value.type();

    if (type == StringType) {
        UString ustring = value.toString(exec);
        CString cstring = ustring.UTF8String();
        NPString string = { (const NPUTF8 *)cstring.c_str(), cstring.size() };
        NPN_InitializeVariantWithStringCopy (result, &string );
    }
    else if (type == NumberType) {
        NPN_InitializeVariantWithDouble (result, value.toNumber(exec));
    }
    else if (type == BooleanType) {
        NPN_InitializeVariantWithBool (result, value.toBoolean(exec));
    }
    else if (type == UnspecifiedType) {
        NPN_InitializeVariantAsUndefined(result);
    }
    else if (type == NullType) {
        NPN_InitializeVariantAsNull(result);
    }
    else if (type == ObjectType) {
        KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
        if (objectImp->classInfo() == &KJS::RuntimeObjectImp::info) {
            KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
            CInstance *instance = static_cast<CInstance*>(imp->getInternalInstance());
            NPN_InitializeVariantWithObject (result, instance->getObject());
        }
        else {

            KJS::Interpreter *originInterpreter = exec->interpreter();
            const Bindings::RootObject *originExecutionContext = rootForInterpreter(originInterpreter);

            KJS::Interpreter *interpreter = 0;
            if (originInterpreter->isGlobalObject(value)) {
                interpreter = originInterpreter->interpreterForGlobalObject (value.imp());
            }

            if (!interpreter)
                interpreter = originInterpreter;

            const Bindings::RootObject *executionContext = rootForInterpreter(interpreter);
            if (!executionContext) {
                Bindings::RootObject *newExecutionContext = new KJS::Bindings::RootObject(0);
                newExecutionContext->setInterpreter (interpreter);
                executionContext = newExecutionContext;
            }

            NPObject *obj = (NPObject *)exec->interpreter()->createLanguageInstanceForValue (exec, Instance::CLanguage, value.toObject(exec), originExecutionContext, executionContext);
            NPN_InitializeVariantWithObject (result, obj);
            _NPN_ReleaseObject (obj);
        }
    }
    else
        NPN_InitializeVariantAsUndefined(result);
}
jvalue KJS::Bindings::convertValueToJValue (KJS::ExecState *exec, KJS::Value value, JNIType _JNIType, const char *javaClassName)
{
    jvalue result;
    double d = 0;
   
    d = value.toNumber(exec);
    switch (_JNIType){
        case object_type: {
            result.l = (jobject)0;
            
            // First see if we have a Java instance.
            if (value.type() == KJS::ObjectType){
                KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
                if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
                    KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
                    JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
                    result.l = instance->javaInstance();
                }
                else if (strcmp(objectImp->classInfo()->className, "RuntimeArray") == 0) {
                    KJS::RuntimeArrayImp *imp = static_cast<KJS::RuntimeArrayImp *>(value.imp());
                    JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
                    result.l = array->javaArray();
                }
            }
            
            // Now convert value to a string if the target type is a java.lang.string.
            if (result.l == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
                KJS::UString stringValue = value.toString(exec);
                JNIEnv *env = getJNIEnv();
                jobject javaString = env->functions->NewString (env, (const jchar *)stringValue.data(), stringValue.size());
                result.l = javaString;
            }
        }
        break;
        
        case boolean_type: {
            result.z = (jboolean)d;
        }
        break;
            
        case byte_type: {
            result.b = (jbyte)d;
        }
        break;
        
        case char_type: {
            result.c = (jchar)d;
        }
        break;

        case short_type: {
            result.s = (jshort)d;
        }
        break;

        case int_type: {
            result.i = (jint)d;
        }
        break;

        case long_type: {
            result.j = (jlong)d;
        }
        break;

        case float_type: {
            result.f = (jfloat)d;
        }
        break;

        case double_type: {
            result.d = (jdouble)d;
        }
        break;
            
        break;

        case invalid_type:
        default:
        case void_type: {
            //bzero (&result, sizeof(jvalue));
            memset(&result, 0, sizeof(jvalue));
        }
        break;
    }
    return result;
}