ClRcT corAmfMibTreeInitialize(void)
{
    ClRcT rc = CL_OK;
    ClVersionT version = {'B', 0x1 , 0x1};
    ClCorMOIdT moId;
    ClCorMOIdT chassisMoid;
    ClAmsEntityBufferT nodeList = {0};
    ClAmsEntityBufferT suList = {0};
    ClAmsEntityBufferT compList = {0};
    ClAmsEntityBufferT sgList = {0};
    ClAmsEntityBufferT siList = {0};
    ClAmsEntityBufferT csiList = {0};
    ClCorClassTypeT classIds[CL_AMS_ENTITY_TYPE_MAX+2] = {0};
    ClInt32T chassisId = 0;
    ClNameT entityName = {0};
    ClUint32T i = 0;
    static ClUint32T extendedIndexTable[CL_AMS_MGMT_OI_EXTENDED_CLASS_MAX];

    rc = corAmfEntityInitialize();
    if(rc != CL_OK) goto out;

    rc = clAmsMgmtInitialize(&mgmtHandle,  NULL, &version);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "Mgmt initialize returned [%#x]", rc);
        goto out;
    }
    
    snprintf(entityName.value, sizeof(entityName.value), "%s:%d", "\\Chassis", chassisId);
    entityName.length = strlen(entityName.value);
    rc = clCorMoIdNameToMoIdGet(&entityName, &chassisMoid);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "Cor moid get returned [%#x] for name [%s]",
                   rc, entityName.value);
        goto out;
    }

    for(i = 0; i <= CL_AMS_ENTITY_TYPE_MAX; ++i)
    {
        rc = corAmfEntityClassGet(i, classIds + i);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "Entity class for [%s] not found",
                       CL_AMS_STRING_ENTITY_TYPE(i));
            goto out;
        }
    }

    if( (rc = clAmsMgmtGetNodeList(mgmtHandle, &nodeList)) != CL_OK)
    {
        clLogError("COR", "AMF", "Node list returned [%#x]", rc);
        goto out;
    }


    /*
     * Create objects for nodes/sus/comps/sgs/sis/csis
     */
    for(i = 0; i < nodeList.count; ++i)
    {
        memcpy(&moId, &chassisMoid, sizeof(moId));
        clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_NODE], i);
        rc = corAmfObjectCreate(i, &nodeList.entity[i], &moId);
        if(rc != CL_OK) goto out;
    }

    rc = clAmsMgmtGetSUList(mgmtHandle, &suList);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "SU list get returned [%#x]", rc);
        goto out;
    }

    for(i = 0; i < suList.count; ++i)
    {
        memcpy(&moId, &chassisMoid, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_SU], i);
        CL_ASSERT(rc == CL_OK);
        rc = corAmfObjectCreate(i, &suList.entity[i], &moId);
        if(rc != CL_OK) goto out;
    }
    
    rc = clAmsMgmtGetCompList(mgmtHandle, &compList);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "Comp list get returned [%#x]", rc);
        goto out;
    }

    for(i = 0; i < compList.count; ++i)
    {
        memcpy(&moId, &chassisMoid, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_COMP], i);
        CL_ASSERT(rc == CL_OK);
        rc = corAmfObjectCreate(i, &compList.entity[i], &moId);
        if(rc != CL_OK) goto out;
    }

    rc = clAmsMgmtGetSGList(mgmtHandle, &sgList);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "SG list returned [%#x]", rc);
        goto out;
    }

    for(i = 0; i < sgList.count; ++i)
    {
        ClAmsEntityBufferT rankList = {0};
        memcpy(&moId, &chassisMoid, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_SG], i);
        CL_ASSERT(rc == CL_OK);
        rc = corAmfObjectCreate(i, &sgList.entity[i], &moId);
        if(rc != CL_OK) goto out;
        rc = clAmsMgmtGetSGSIList(mgmtHandle, &sgList.entity[i], &rankList);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SG [%s] si list returned [%#x]",
                       sgList.entity[i].name.value, rc);
            goto out;
        }
        rc = corAmfExtendedClassObjectCreate("saAmfSGSIRankTable",
                                             &sgList.entity[i],
                                             &chassisMoid,
                                             rankList.count,
                                             &extendedIndexTable[CL_AMS_MGMT_OI_SGSIRANK],
                                             &i);
        if(rankList.entity)
        {
            clHeapFree(rankList.entity);
            rankList.entity = NULL;
            rankList.count = 0;
        }
        
        rc = clAmsMgmtGetSGSUList(mgmtHandle, &sgList.entity[i], &rankList);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SG [%s] su list returned [%#x]",
                       sgList.entity[i].name.value, rc);
            goto out;
        }
        rc = corAmfExtendedClassObjectCreate("saAmfSGSURankTable",
                                             &sgList.entity[i],
                                             &chassisMoid,
                                             rankList.count,
                                             &extendedIndexTable[CL_AMS_MGMT_OI_SGSURANK],
                                             &i);
        if(rankList.entity)
        {
            clHeapFree(rankList.entity);
            rankList.count = 0;
        }
    }

    rc = clAmsMgmtGetSIList(mgmtHandle, &siList);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "SI list get returned [%#x]", rc);
        goto out;
    }

    for(i = 0; i < siList.count; ++i)
    {
        ClAmsEntityBufferT list = {0};
        memcpy(&moId, &chassisMoid, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_SI], i);
        CL_ASSERT(rc == CL_OK);
        rc = corAmfObjectCreate(i, &siList.entity[i], &moId);
        if(rc != CL_OK) goto out;
        
        rc = clAmsMgmtGetSIDependenciesList(mgmtHandle, &siList.entity[i],
                                            &list);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SI [%s] dependencies list returned [%#x]",
                       siList.entity[i].name.value, rc);
            goto out;
        }
        if(list.count)
        {
            rc = corAmfExtendedClassObjectCreate("saAmfSISIDepTable",
                                                 &siList.entity[i],
                                                 &chassisMoid,
                                                 list.count,
                                                 &extendedIndexTable[CL_AMS_MGMT_OI_SISIDEP],
                                                 &i);
        }

        if(list.entity)
        {
            clHeapFree(list.entity);
            list.count = 0;
        }
        rc = clAmsMgmtGetSISURankList(mgmtHandle, &siList.entity[i], &list);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SI [%s] su rank list returned [%#x]",
                       siList.entity[i].name.value, rc);
            goto out;
        }
        if(list.count)
        {
            rc = corAmfExtendedClassObjectCreate("saAmfSUsperSIRankTable",
                                                 &siList.entity[i],
                                                 &chassisMoid,
                                                 list.count,
                                                 &extendedIndexTable[CL_AMS_MGMT_OI_SUSPERSIRANK],
                                                 &i);
        }
        if(list.entity)
        {
            list.count = 0;
            clHeapFree(list.entity);
        }
    }
    
    rc = clAmsMgmtGetCSIList(mgmtHandle, &csiList);
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "CSI list get returned [%#x]", rc);
        goto out;
    }
    for(i = 0; i < csiList.count; ++i)
    {
        ClAmsCSINVPBufferT buffer = {0};
        ClAmsEntityBufferT list = {0};
        memcpy(&moId, &chassisMoid, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_CSI], i);
        CL_ASSERT(rc == CL_OK);
        rc = corAmfObjectCreate(i, &csiList.entity[i], &moId);
        if(rc != CL_OK) goto out;

        rc = clAmsMgmtGetCSINVPList(mgmtHandle, &csiList.entity[i], &buffer);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "CSI [%s] nvp list returned [%#x]",
                       csiList.entity[i].name.value, rc);
            goto out;
        }
        
        rc = corAmfExtendedClassObjectCreate("saAmfCSINameValueTable",
                                             &csiList.entity[i],
                                             &chassisMoid,
                                             buffer.count,
                                             &extendedIndexTable[CL_AMS_MGMT_OI_CSINAMEVALUE],
                                             &i);
        if(buffer.nvp)
        {
            clHeapFree(buffer.nvp);
        }

        rc = clAmsMgmtGetCSIDependenciesList(mgmtHandle, &csiList.entity[i],
                                             &list);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "CSI [%s] dependencies list returned [%#x]",
                       csiList.entity[i].name.value, rc);
            goto out;
        }
        
        rc = corAmfExtendedClassObjectCreate("saAmfCSICSIDepTable",
                                             &csiList.entity[i],
                                             &chassisMoid,
                                             list.count,
                                             &extendedIndexTable[CL_AMS_MGMT_OI_CSICSIDEP],
                                             &i);
        if(list.entity)
        {
            clHeapFree(list.entity);
        }
    }

    /*
     * We are here when the objects are all created. Do a commit
     */
    rc = corAmfObjectCommit();
    if(rc != CL_OK)
    {
        clLogError("COR", "AMF", "Object commit returned [%#x]", rc);
        goto out;
    }

    clLogNotice("COR", "AMF", "COR AMF tree successfully initialized");

    out:
    if(nodeList.entity) 
        clHeapFree(nodeList.entity);
    if(suList.entity)   
        clHeapFree(suList.entity);
    if(compList.entity) 
        clHeapFree(compList.entity);
    if(sgList.entity)   
        clHeapFree(sgList.entity);
    if(siList.entity)   
        clHeapFree(siList.entity);
    if(csiList.entity) 
        clHeapFree(csiList.entity);
    return rc;
}
ClRcT clAmsMgmtOIInitialize(ClAmsMgmtHandleT *pHandle, 
                            ClRcT (*pClAmsMgmtOIConfigAttributesGet)
                            (ClAmsEntityConfigT*, ClCorAttributeValueListPtrT pAttrList),
                            ClRcT (*pClAmsMgmtOIExtendedConfigAttributesGet)
                            (ClAmsMgmtOIExtendedClassTypeT type, 
                             ClAmsMgmtOIExtendedEntityConfigT *pConfig,
                             ClCorClassTypeT *pClassType,
                             ClCorAttributeValueListT *pAttrList))
{
    ClRcT rc = CL_OK;
    ClAmsMgmtHandleT handle = 0;
    ClAmsEntityBufferT buffer[CL_AMS_ENTITY_TYPE_MAX+2] = {{0}};
    ClVersionT version = {'B', 0x1, 0x1};
    ClCorTxnSessionIdT txnSession = 0;
    ClUint32T i;
    ClCorAddrT appAddress = {0};
    SaNameT chassisInstance = {0};
    ClUint32T chassisId = 0;

    if(!pClAmsMgmtOIConfigAttributesGet)
        return CL_AMS_RC(CL_ERR_INVALID_PARAMETER);

    rc = clOsalMutexInit(&gClAmsMgmtOICacheMutex);
    CL_ASSERT(rc == CL_OK);

    rc = clEoMyEoIocPortGet(&appAddress.portId);
    if(rc != CL_OK) 
        return rc;
    appAddress.nodeAddress = clIocLocalAddressGet();

    rc = clAmsMgmtInitialize(&handle, NULL, &version);
    if(rc != CL_OK)
    {
        return rc;
    }
    snprintf(chassisInstance.value, sizeof(chassisInstance.value),
             "%s:%d", "\\Chassis", chassisId);
    chassisInstance.length = strlen(chassisInstance.value);
    rc = clCorMoIdNameToMoIdGet(&chassisInstance, &gClChassisMoid);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "COR moid get for [%s] returned [%#x]",
                   chassisInstance.value, rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSGList(handle, &buffer[CL_AMS_ENTITY_TYPE_SG]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SG list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSIList(handle, &buffer[CL_AMS_ENTITY_TYPE_SI]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SI list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetCSIList(handle, &buffer[CL_AMS_ENTITY_TYPE_CSI]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get CSI list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetNodeList(handle, &buffer[CL_AMS_ENTITY_TYPE_NODE]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get NODE list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSUList(handle, &buffer[CL_AMS_ENTITY_TYPE_SU]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SU list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetCompList(handle, &buffer[CL_AMS_ENTITY_TYPE_COMP]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get COMP list returned [%#x]", rc);
        goto out_free;
    }
    /*
     * Now fetch the moid for each of the entities and build the cache.
     */
    for(i = 0; i <= CL_AMS_ENTITY_TYPE_MAX; ++i)
    {
        ClAmsEntityBufferT *pBuffer = &buffer[i];
        ClUint32T j;
        if(!pBuffer->count || !pBuffer->entity)
            continue;
        gClAmsMgmtOIIndexTable[i] = pBuffer->count;
        for(j = 0; j < pBuffer->count; ++j)
        {
            ClCorMOIdT moid = {{{0}}};
            rc = clAmsMgmtOIMoIdGet(handle, pBuffer->entity+j, &moid);
            if(rc != CL_OK)
            {
                continue;
            }
            clAmsMgmtOICacheAdd(clCorMoIdToInstanceGet(&moid), pBuffer->entity+j);
            /*
             * Required for instances exceeding the pre-configured limit.
             */
             rc = clCorOIRegister(&moid, &appAddress);
             if(rc != CL_OK)
             {
                 continue;
             }
            rc = clCorPrimaryOISet(&moid, &appAddress);
            if(rc != CL_OK)
            {
                /*
                 * Ignore as it could be already set by the active.
                 */
                continue;
            }
            clAmsMgmtOIConfigAttributeSet(handle, &txnSession, &moid, pBuffer->entity+j, pClAmsMgmtOIConfigAttributesGet);
            clAmsMgmtOIExtendedConfigAttributeSet(handle, &txnSession, pBuffer->entity+j,
                                                  pClAmsMgmtOIExtendedConfigAttributesGet);
        }
    }
    rc = clCorTxnSessionCommit(txnSession);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "AMF OI config commit returned [%#x]", rc);
    }
    else
    {
        clLogNotice("AMF", "MGMT", "Entity cache successfully initialized");
        gClAmsMgmtOIInitialized = CL_TRUE;
    }

    out_free:
    for(i = 0; i <= CL_AMS_ENTITY_TYPE_MAX; ++i)
    {
        if(buffer[i].entity) clHeapFree(buffer[i].entity);
        if(rc != CL_OK) clAmsMgmtOICacheDestroy(i);
    }
    if(rc != CL_OK)
    {
        for(i = 0; i < CL_AMS_MGMT_OI_EXTENDED_CLASS_MAX; ++i)
            clAmsMgmtOIExtendedCacheDestroy(i);
    }
    if(rc == CL_OK && pHandle)
        *pHandle = handle;
    else 
        clAmsMgmtFinalize(handle);

    return rc;
}