ChromiumDLL::JSObjHandle JSBridgeTestExtender::execute(const ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptFunctionArgs>& args)
{
	std::string strFunction(args->function);

	if (strFunction == "functionCallback")
	{
		return args->factory->CreateBool(true);
	}
	else if (strFunction == "regCallbacks")
	{
		if (args->argc >= 1)
			m_fnV1 = args->argv[0];
		if (args->argc >= 2)
			m_fnV2 = args->argv[1];
		if (args->argc >= 3)
			m_fnV3 = args->argv[2];
		if (args->argc >= 4)
			m_fnDT = args->argv[3];

		assert(m_fnV1 && m_fnV1->isFunction());
		assert(m_fnV2 && m_fnV2->isFunction());
		assert(m_fnV3 && m_fnV3->isFunction());
		assert(m_fnDT && m_fnDT->isFunction());

		if (m_fnV1)
		{
			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> go = args->context->getGlobalObject();
			assert(go);

			if (go)
			{
				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> jsobject = go->getValue("jsobject");
				assert(jsobject && jsobject->isObject());

				if (jsobject && jsobject->isObject())
				{
					jsobject->setValue("count", args->factory->CreateInt(jsobject->getNumberOfKeys()));
					jsobject->setValue("second", jsobject->getValue("first"));
					jsobject->deleteValue("first");
					jsobject->setValue("third", args->factory->CreateInt(3));
				}


				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> jsarray = go->getValue("jsarray");
				assert(jsarray && jsarray->isArray());

				if (jsarray && jsarray->isArray())
				{
					jsarray->setValue(1, jsarray->getValue(0));
					jsarray->setValue(0, args->factory->CreateInt(jsarray->getNumberOfKeys()));
					jsarray->deleteValue(2);
					jsarray->setValue(3, args->factory->CreateInt(3));
				}
			}

			m_fnV1->executeFunction(args);
		}

		if (m_fnV2)
		{

			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> go = args->context->getGlobalObject();
			assert(go);

			if (go)
			{
				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> obj = args->factory->CreateObject();
				obj->setValue("a", args->factory->CreateInt(123));
				go->setValue("cppobject", obj);
			}

			m_fnV2->executeFunction(args);
		}

		if (m_fnV3)
		{
			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> go = args->context->getGlobalObject();
			assert(go);

			if (go)
			{
				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> jscallback = go->getValue("jscallback");
				assert(jscallback && jscallback->isFunction());

				if (jscallback && jscallback->isFunction())
					jscallback->executeFunction(args);
			}

			m_fnV3->executeFunction(args);
		}

		if (m_fnDT)
		{
			m_fnDT->executeFunction(new DataTypeArgs(args, "undefined", args->factory->CreateUndefined()));
			m_fnDT->executeFunction(new DataTypeArgs(args, "null", args->factory->CreateNull()));
			m_fnDT->executeFunction(new DataTypeArgs(args, "double", args->factory->CreateDouble(123.456)));
			m_fnDT->executeFunction(new DataTypeArgs(args, "bool", args->factory->CreateBool(true)));
			m_fnDT->executeFunction(new DataTypeArgs(args, "int", args->factory->CreateInt(789)));
			m_fnDT->executeFunction(new DataTypeArgs(args, "string", args->factory->CreateString("Im a string")));

			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> obj = args->factory->CreateObject();
			obj->setValue("a", args->factory->CreateInt(123));

			m_fnDT->executeFunction(new DataTypeArgs(args, "object", obj));


			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> arr = args->factory->CreateArray();
			arr->setValue(0, args->factory->CreateInt(190));
			arr->setValue(1, args->factory->CreateInt(1));
			arr->setValue(2, args->factory->CreateInt(84));

			m_fnDT->executeFunction(new DataTypeArgs(args, "array", arr));


			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> funct = args->factory->CreateFunction("functionCallback", this);
			m_fnDT->executeFunction(new DataTypeArgs(args, "function", funct));
		}
	}
	else if (strFunction == "dataTypes")
	{
		if (args->argc < 2 || !args->argv[0]->isString())
		{
			assert(false);
		}
		else
		{
			char szDataType[255] = { 0 };
			args->argv[0]->getStringValue(szDataType, 255);

			std::string strDataType(szDataType);

			ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> val = args->argv[1];

			if (strDataType == "undefined") {
				assert(val->isUndefined());
			}
			else if (strDataType == "null") {
				assert(val->isNull());
			}
			else if (strDataType == "double") {
				assert(val->isDouble());
				assert((123.456 - val->getDoubleValue()) < 0.001);
			}
			else if (strDataType == "bool") {
				assert(val->isBool());
				assert(val->getBoolValue());
			}
			else if (strDataType == "int") {
				assert(val->isInt());
				assert(val->getIntValue() == 789);
			}
			else if (strDataType == "string") {
				assert(val->isString());

				char szVal[255] = { 0 };
				val->getStringValue(szVal, 255);

				assert(std::string("Im a string") == szVal);
			}
			else if (strDataType == "function") {
				assert(val->isFunction());
			}
			else if (strDataType == "object") {
				assert(val->isObject());

				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> a = val->getValue("a");
				assert(a->isInt() && a->getIntValue() == 123);
			}
			else if (strDataType == "array") {
				assert(val->isArray());
				assert(val->getArrayLength() == 3);

				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> a = val->getValue(0);
				assert(a->isInt() && a->getIntValue() == 190);

				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> b = val->getValue(1);
				assert(b->isInt() && b->getIntValue() == 1);

				ChromiumDLL::RefPtr<ChromiumDLL::JavaScriptObjectI> c = val->getValue(2);
				assert(c->isInt() && c->getIntValue() == 84);
			}

			if (m_fnDT)
				m_fnDT->executeFunction(args);
		}
	}
	else if (strFunction == "assert")
	{
		assert(false);
	}

	return ChromiumDLL::JSObjHandle();
}
STDMETHODIMP CProjectDBI::GetInstancesForDataType
(
    /*[in, string]*/ BSTR   sDataType,
    /*[out]*/ SAFEARRAY**   pparrInstancePaths
)
{
    if (pparrInstancePaths == NULL)
    {
        return E_POINTER;
    }

    CString         strDataType(sDataType); // data type of instances
    CStringArray    astrInstancePaths;      // array to collect instance paths

    // run over all configurations and resources
    int iNumConf, iConf;
    CConfigurationDBI*  pConfig;

    HRESULT hr;

    hr = Load();
    if(hr != S_OK)
    {
        return hr;
    }

    iNumConf = m_Configurations.GetSize();

    for(iConf = 0; iConf < iNumConf; ++iConf)
    {
        pConfig = m_Configurations[iConf];
        pConfig->AddInstancesForDataType(strDataType, astrInstancePaths);
    }

    long lNumInstances = astrInstancePaths.GetSize();

    // now fill safe array with instances
    SAFEARRAYBOUND  Bound;

    Bound.lLbound = 0;
    Bound.cElements = lNumInstances;

    *pparrInstancePaths = ::SafeArrayCreate(VT_BSTR, 1, &Bound);
    if (NULL == (*pparrInstancePaths))
    {
        return E_FAIL;
    }

    try
    {
        for (long lInstance = 0; lInstance < lNumInstances; ++lInstance)
        {
            CComBSTR sInstancePath(astrInstancePaths[lInstance]);
            hr = ::SafeArrayPutElement(*pparrInstancePaths, &lInstance,
                                       (void*)sInstancePath);
            if (FAILED(hr))
            {
                ::SafeArrayDestroy(*pparrInstancePaths);
                return E_FAIL;
            }
        }
    }
    catch (CMemoryException* e)
    {
        e->Delete();
        return E_OUTOFMEMORY;
    }
    return S_OK;
}