ECode MultiFloatValuesHolder::SetupSetter(
    /* [in] */ IInterface* targetClass)
{
    if (mJniSetter != NULL) {
        return NOERROR;
    }
    // try {
    AutoLock lock(mPropertyMapLock);
    // mPropertyMapLock.writeLock().lock();
    AutoPtr<IClassInfo> info = TransformClassInfo(targetClass);
    AutoPtr<MethodMap> propertyMap = sJNISetterPropertyMap[info];

    typename ClassMethodMap::Iterator it = sJNISetterPropertyMap.Find(info);
    if ((it != sJNISetterPropertyMap.End()) && (it->mSecond != NULL)) {
        propertyMap = it->mSecond;
        typename MethodMap::Iterator it2 = propertyMap->Find(mPropertyName);
        if ((it2 != propertyMap->End()) && (it2->mSecond != NULL)) {
            mJniSetter = it2->mSecond;
        }
    }

    if (mJniSetter == NULL) {
        String methodName = GetMethodName(String("Set"), mPropertyName);
        CalculateValue(0.f);
        AutoPtr<IArrayList> values;
        GetAnimatedValue((IInterface**)&values);
        Int32 numParams = 0;
        values->GetSize(&numParams);

        try {
            mJniSetter = nGetMultipleFloatMethod(info, methodName, numParams);
        } catch (NoSuchMethodError e) {
            // try without the 'set' prefix
            mJniSetter = nGetMultipleFloatMethod(info, mPropertyName, numParams);
        }
        if (mJniSetter != NULL) {
            if (propertyMap == NULL) {
                propertyMap = new MethodMap();
                sJNISetterPropertyMap[info] = propertyMap;
            }
            (*propertyMap)[mPropertyName] = mJniSetter;
        }
    }
    // } finally {
    //     mPropertyMapLock.writeLock().unlock();
    // }
    return NOERROR;
}
ECode MultiFloatValuesHolder::SetAnimatedValue(
    /* [in] */ IInterface* target)
{
    AutoPtr<IInterface> v;
    GetAnimatedValue((IInterface**)&v);
    AutoPtr<IArrayList> list = IArrayList::Probe(v);
    Int32 numParameters = 0;
    assert(list != NULL);
    list->GetSize(&numParameters);

    AutoPtr<ArrayOf<Float> > values = ArrayOf<Float>::Alloc(numParameters);
    Float fv = 0.f;
    for (Int32 i = 0; i < numParameters; i++) {
        AutoPtr<IFloat> value;
        list->Get(i, (IInterface**)&value);
        value->GetValue(&fv);
        (*values)[i] = fv;
    }
    if (mJniSetter != 0) {
        switch (numParameters) {
            case 1: {
                nCallFloatMethod(target, mJniSetter, (*values)[0]);
                break;
            }
            case 2: {
                nCallTwoFloatMethod(target, mJniSetter, (*values)[0], (*values)[1]);
                break;
            }
            case 4: {
                nCallFourFloatMethod(target, mJniSetter, (*values)[0], (*values)[1],
                        (*values)[2], (*values)[3]);
                break;
            }
            default: {
                nCallMultipleFloatMethod(target, mJniSetter, values);
                break;
            }
        }
    }
    return NOERROR;
}
ECode Int32PropertyValuesHolder::SetAnimatedValue(
    /* [in] */ IInterface* target)
{
    if (mInt32Property != NULL) {
        return mInt32Property->SetValue(target, mInt32AnimatedValue);
    }

    AutoPtr<IInterface> animatedValue;
    GetAnimatedValue((IInterface**)&animatedValue);
    if (mProperty != NULL) {
        mProperty->Set(target, animatedValue);
        return NOERROR;
    }

    if (mJniSetter != NULL) {
        AutoPtr<IArgumentList> args;
        mJniSetter->CreateArgumentList((IArgumentList**)&args);
        AutoPtr<IFunctionInfo> funcInfo;
        args->GetFunctionInfo((IFunctionInfo**)&funcInfo);
        AutoPtr<IParamInfo> paramInfo;
        funcInfo->GetParamInfoByIndex(0, (IParamInfo**)&paramInfo);
        AutoPtr<IDataTypeInfo> dataTypeInfo;
        paramInfo->GetTypeInfo((IDataTypeInfo**)&dataTypeInfo);
        CarDataType carType;
        dataTypeInfo->GetDataType(&carType);
        if(carType == CarDataType_Int32)
        {
            args->SetInputArgumentOfInt32(0, mInt32AnimatedValue);
        } else if(carType == CarDataType_Interface){
            args->SetInputArgumentOfObjectPtr(0, animatedValue);
        } else {
            assert(0);
        }
        mJniSetter->Invoke(target, args);
        return NOERROR;
    }
    if (mSetter != NULL) {
        AutoPtr<IArgumentList> args;
        mSetter->CreateArgumentList((IArgumentList**)&args);
        AutoPtr<IFunctionInfo> funcInfo;
        args->GetFunctionInfo((IFunctionInfo**)&funcInfo);
        AutoPtr<IParamInfo> paramInfo;
        funcInfo->GetParamInfoByIndex(0, (IParamInfo**)&paramInfo);
        AutoPtr<IDataTypeInfo> dataTypeInfo;
        paramInfo->GetTypeInfo((IDataTypeInfo**)&dataTypeInfo);
        CarDataType carType;
        dataTypeInfo->GetDataType(&carType);
        if(carType == CarDataType_Int32)
        {
            args->SetInputArgumentOfInt32(0, mInt32AnimatedValue);
        } else if(carType == CarDataType_Interface){
            args->SetInputArgumentOfObjectPtr(0, animatedValue);
        } else {
            assert(0);
        }
        mSetter->Invoke(target, args);

        return NOERROR;
    }
    return NOERROR;
}