JSBool jsval_to_TProductInfo(JSContext *cx, jsval v, TProductInfo* ret)
{
    JSObject* tmp = JSVAL_TO_OBJECT(v);
    if (!tmp) {
        LOGD("jsval_to_TProductInfo: the jsval is not an object.");
        return JS_FALSE;
    }

    JSObject* it = JS_NewPropertyIterator(cx, tmp);

    while (true)
    {
        jsid idp;
        jsval key;
        if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key))
            return JS_FALSE; // error
        if (key == JSVAL_VOID)
            break; // end of iteration
        if (! JSVAL_IS_STRING(key))
            continue; // ignore integer properties
        jsval value;
        JS_GetPropertyById(cx, tmp, idp, &value);
        if (! JSVAL_IS_STRING(value))
            continue; // ignore integer properties

        JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx);
        JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx);

        (*ret)[strWrapper.get()] = strWrapper2.get();
        LOGD("iterate object: key = %s, value = %s", strWrapper.get().c_str(), strWrapper2.get().c_str());
    }

    return JS_TRUE;
}
bool jsval_to_FBInfo(JSContext *cx, jsval v, StringMap* ret)
{
	JSObject* tmp = JSVAL_TO_OBJECT(v);
	if (!tmp) {
		LOGD("jsval_to_TProductInfo: the jsval is not an object.");
		return false;
	}

	JSObject* it = JS_NewPropertyIterator(cx, tmp);

	while (true)
	{
		jsid idp;
		jsval key;
		if (! JS_NextProperty(cx, it, &idp) || ! JS_IdToValue(cx, idp, &key))
			return false; // error
		if (key == JSVAL_VOID)
			break; // end of iteration
		if (! JSVAL_IS_STRING(key))
			continue; // ignore integer properties
		JS::RootedValue value(cx);
		JS_GetPropertyById(cx, tmp, idp, &value);

//		if (! JSVAL_IS_STRING(value))
//			continue; // ignore integer properties
		if(JSVAL_IS_STRING(value))
		{

			JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx);
			JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx);

			ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), strWrapper2.get()));
		}
		else if(JSVAL_IS_NUMBER(value))
		{
			double number = 0.0;
			JS::ToNumber(cx, value, &number);

			std::stringstream ss;
			ss << number;

			JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx);
			//JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx);

			ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), ss.str()));
		}
		else if(JSVAL_IS_BOOLEAN(value))
		{
			bool boolVal = JS::ToBoolean(value);
			JSStringWrapper strWrapper(JSVAL_TO_STRING(key), cx);
			//JSStringWrapper strWrapper2(JSVAL_TO_STRING(value), cx);
			std::string boolstring = boolVal ? "true" : "false";
			ret->insert(std::map<std::string, std::string>::value_type(strWrapper.get(), boolstring));
		}
	}

	return true;
}