void PVMFProtocolEngineNodeRegistry::AddLoadableModules()
{
    LOGINFO((0, "PVMFProtocolEngineNodeRegistry::AddLoadableModules() IN"));

#if USE_LOADABLE_MODULES

    OsclConfigFileList aCfgList;
    // collects all config files from the project specified directory
    if (NULL != PV_DYNAMIC_LOADING_CONFIG_FILE_PATH)
    {
        OSCL_HeapString<OsclMemAllocator> configFilePath = PV_DYNAMIC_LOADING_CONFIG_FILE_PATH;
        aCfgList.Populate(configFilePath);
    }
    // populate libraries from all config files
    for (uint k = 0; k < aCfgList.Size(); k++)
    {
        OsclLibraryList libList;
        libList.Populate(PVMF_PROTOCOL_ENGINE_NODE_REGISTRY_POPULATOR_INTERFACE, aCfgList.GetConfigfileAt(k));

        for (uint32 i = 0; i < libList.Size(); i++)
        {
            OsclSharedLibrary* lib = OSCL_NEW(OsclSharedLibrary, ());
            if (lib->LoadLib(libList.GetLibraryPathAt(i)) == OsclLibSuccess)
            {
                OsclAny* interfacePtr = NULL;
                OsclLibStatus result = lib->QueryInterface(PVMF_PROTOCOL_ENGINE_NODE_REGISTRY_POPULATOR_INTERFACE, (OsclAny*&)interfacePtr);
                if (result == OsclLibSuccess && interfacePtr != NULL)
                {
                    struct PVProtocolEngineNodeSharedLibInfo *libInfo =
                        (struct PVProtocolEngineNodeSharedLibInfo *)oscl_malloc(sizeof(struct PVProtocolEngineNodeSharedLibInfo));
                    if (NULL != libInfo)
                    {
                        libInfo->iLib = lib;

                        PVMFProtocolEngineNodeRegistryPopulatorInterface* nodeLibIntPtr = OSCL_DYNAMIC_CAST(PVMFProtocolEngineNodeRegistryPopulatorInterface*, interfacePtr);
                        libInfo->iNodeLibIfacePtr = nodeLibIntPtr;
                        nodeLibIntPtr->Register(this);

                        // save for depopulation later
                        iNodeLibInfoList.push_front(libInfo);
                        continue;
                    }
                }
            }
            lib->Close();
            OSCL_DELETE(lib);
        }
// ALL the standard OpenMAX IL core functions are implemented below
static OMX_ERRORTYPE _OMX_MasterInit(OMXMasterCoreGlobalData *data)
{
    OMX_ERRORTYPE Status = OMX_ErrorNone;
    OMX_U32 jj;
    OMX_U32 index;
    OMX_U32 master_index = 0;
    OMX_U32 component_index = 0;

    /*
    ** Step 1. Populate all the config files present in the specified path.
    ** Step 2. Populate all the libraries from the .cfg files that claim to support the OMX_INTERFACE_ID.
    ** Step 3. For these libraries, validate whether they really support the ID by doing a QueryInterface().
    */

    // Step 1
    OsclConfigFileList aCfgList;
    OSCL_HeapString<OsclMemAllocator> configFilePath = PV_DYNAMIC_LOADING_CONFIG_FILE_PATH;
    aCfgList.Populate(configFilePath, OsclConfigFileList::ESortByName);

    // array of ptrs to various cores, one for every valid configuration
    OMXInterface** pInterface = (OMXInterface**)OSCL_MALLOC(aCfgList.Size() * sizeof(OMXInterface *));
    if (pInterface == NULL)
    {
        return OMX_ErrorInsufficientResources;
    }
    // set the global ptr to this array
    data->iInterface = (void*)pInterface;

    // array of ptrs to the omx shared libraries, one for every valid configuration
    OsclSharedLibrary** pLibrary = (OsclSharedLibrary**)OSCL_MALLOC(aCfgList.Size() * sizeof(OsclSharedLibrary *));
    if (pLibrary == NULL)
    {
        return OMX_ErrorInsufficientResources;
    }
    // set the global ptr to this array
    //
    data->iOMXLibrary = (void*)pLibrary;

    for (uint ii = 0; ii < aCfgList.Size(); ii++)
    {
        // Step 2
        OsclLibraryList libList;
        libList.Populate(OMX_INTERFACE_ID, aCfgList.GetConfigfileAt(ii));

        for (uint jj = 0; (jj < libList.Size()) && ((data->iNumOMXCores) < aCfgList.Size()); jj++)
        {
            OsclSharedLibrary* lib = OSCL_NEW(OsclSharedLibrary, ());
            if (lib->LoadLib(libList.GetLibraryPathAt(jj)) == OsclLibSuccess)
            {
                OsclAny* interfacePtr = NULL;
                // Step 3
                OsclLibStatus result = lib->QueryInterface(OMX_INTERFACE_ID, (OsclAny*&)interfacePtr);
                if (result == OsclLibSuccess && interfacePtr != NULL)
                {
                    pLibrary[(data->iNumOMXCores)] = lib;
                    OMXInterface* coreIntPtr = OSCL_DYNAMIC_CAST(OMXInterface*, interfacePtr);
                    pInterface[(data->iNumOMXCores)] = coreIntPtr;
                    (data->iNumOMXCores)++;
                    continue;
                }
            }
            lib->Close();
            OSCL_DELETE(lib);
        }