/**
 *  Get Node Name given MoId.
 *
 *  API to get Logical NodeName given MOId. 
 *
 *
 *  @param pMoId      MOId of the Blade.
 *  @param nodeName   Node name corresponding to blade MOId
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST) If an entry is not present for given MOId<br/>
 *    CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) if moId is NULL <br/>
 */
ClRcT _clCorMoIdToNodeNameGet(ClCorMOIdPtrT pMoId, ClNameT** nodeName)
{
    ClRcT rc;
    ClUint16T OriginalDepth;
    ClCorMOServiceIdT  svcId;
    ClCorMOClassPathT moclassPath;
    CORMOClass_h moClassH;

	if(pMoId == NULL)
		return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);

    /* First check if the MOId passed by the user is valid or not*/

    /* The minimum condition that must be satisfied is */
    /* taht the MO class should exist*/
    rc = clCorMoIdToMoClassPathGet(pMoId, &moclassPath);

    if(CL_OK != rc)
    	CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nCould not get MO class path from MOID", rc);

    /* Check if the MO class exists or not */
    rc = corMOClassHandleGet(&moclassPath, &moClassH);
    
    if (rc != CL_OK)
    	{
    	/* The mo class does not exist. Return*/
    	CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nIncorrect path specified. MO class does not exist\n", rc);
    	}

    /* The user has passed MOId, Since we are going to work on MOId */
    /* Passed by the user, let's store the original depth and svc Id */

    OriginalDepth = pMoId->depth;
    svcId = pMoId->svcId;

    pMoId->svcId = CL_COR_INVALID_SVC_ID;

    for(; pMoId->depth>=1; pMoId->depth--)
    	{
    	/* Find if the MOId is present in the Hash Table */
    	rc = clCntDataForKeyGet(moIdToNodeNameTableHandle, (ClCntKeyHandleT) pMoId, (ClCntDataHandleT *) nodeName);
    	if(CL_OK == rc && *nodeName !=NULL )
    		{
    		/* Found the node name for given MOId. Return.*/
    		/* Before returning restore svc Id and depth */
    		pMoId->depth = OriginalDepth;
    		pMoId->svcId = svcId;
    		return CL_OK;
    		}
    	}

    /* If we are here then the node Name could not be found*/
    /* Restore original depth and svcId and return */

    pMoId->depth = OriginalDepth;
    pMoId->svcId = svcId;

    CL_COR_RETURN_ERROR(CL_DEBUG_TRACE, "\n Node Name not found for given MOId.\n", CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST));

}
/*Currently we are having another API clCorClassDelete for same purpose. However,
  it takes class handle as input. If we plan to remove it. This will be useful.*/
ClRcT
dmClassDelete(ClCorClassTypeT id)
{
    ClRcT ret = CL_OK;
    CORClass_h tmp = 0;
    
    CL_FUNC_ENTER();

    if((!dmGlobal))
      {
        CL_FUNC_EXIT();  
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassDelete (Class:%04x)", id));
    
    /* check if class already present 
     */
    HASH_GET(dmGlobal->classTable, id, tmp);
    if(tmp) 
      {
        ret = dmClassByHandleDelete(tmp);
      } 
    else 
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassDelete (Class:%04x) [Unknown class]", 
                              id));
        
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT);
      }
    
    CL_FUNC_EXIT();
    return (ret);
}
/* The RMD function on the server side which takes care of MOId to NodeName */
ClRcT VDECL(_corMoIdToNodeNameTableOp) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
	ClRcT rc;
	corClientMoIdToNodeNameT tab = {{0}};
	ClNameT		 *nodeName = NULL;
    ClCorNodeDataPtrT  dataNode = NULL;
 
    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("MNT", "EXP", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

	VDECL_VER(clXdrUnmarshallcorClientMoIdToNodeNameT, 4, 0, 0)(inMsgHandle, (ClUint8T*)&tab);
	
	clCorClientToServerVersionValidate(tab.version, rc);
    if(rc != CL_OK)
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED);

	switch (tab.op)
		{
		case COR_MOID_TO_NODE_NAME_GET :
			rc = _clCorMoIdToNodeNameGet(&tab.moId, &nodeName);
			if(rc == CL_OK)
				tab.nodeName = *nodeName;
			else
			{
				rc = CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST);
			}
			break;
		case COR_NODE_NAME_TO_MOID_GET :
			rc = _clCorNodeNameToMoIdGet(&tab.nodeName, &dataNode);
			if(CL_OK == rc)
				{
				/* Copy the MOId */
				tab.moId = *dataNode->pMoId;
				}
			else
            {
				rc = CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST);
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,("For the Nodename %s no MoId found. rc[0x%x]", tab.nodeName.value, rc));
            }
			break;
		default :
			CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nInvalid operation passed\n", CL_ERR_DOESNT_EXIST);
			break;
		}

	if(CL_OK == rc)
		{
		/* Operation successfull. Copy message buffer */
		rc = VDECL_VER(clXdrMarshallcorClientMoIdToNodeNameT, 4, 0, 0)(&tab, outMsgHandle, 0);
		}

	return rc;
	
}
ClRcT VDECL(_corObjectGetNextOp) (ClUint32T cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
    ClRcT rc = CL_OK;
    corObjGetNextInfo_t* pData = NULL; 
    CL_FUNC_ENTER();

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("OBN", "EXP", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

    pData = clHeapAllocate(sizeof(corObjGetNextInfo_t));
    if(pData == NULL)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "NULL input parameter") );
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);   
    }
    if((rc = clXdrUnmarshallcorObjGetNextInfo_t(inMsgHandle, (void *)pData)) != CL_OK)
	{
		clHeapFree(pData);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to Unmarshall corObjGetNextInfo_t"));
		return rc;
	}

  	clCorClientToServerVersionValidate(version, rc);
  	if(rc != CL_OK)
	{
		clHeapFree(pData);
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED);
	}
	
    switch(pData->operation)
    {
        case COR_OBJ_OP_NEXTMO_GET:
		{
              ClCorObjectHandleT nxtOH;
              rc =  _clCorNextMOGet(pData->objHdl, pData->classId, pData->svcId, &nxtOH);
              /* Write to the message*/
              clBufferNBytesWrite (outMsgHandle, (ClUint8T *)&nxtOH, sizeof(ClCorObjectHandleT));
        } 
        break;
        default:
             CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "INVALID OPERATION, rc = %x", rc) );
             rc = CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
        break;
    }
   
    CL_FUNC_EXIT();
	clHeapFree(pData);
    return rc;
}
ClRcT 
clCorDataFrequentSave(char *pFileName, ClTimerTimeOutT  frequency)
{
    ClRcT  rc = CL_OK;
    corPersisInfo_t corData;

	memset(&corData, 0, sizeof(corData));
    CL_FUNC_ENTER();
    CL_DEBUG_PRINT(CL_DEBUG_TRACE,("\n Inside clCorDataFrequentSave \n"));

    /* Validate input parameters */
    if (pFileName == NULL)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "clCorDataFrequentSave: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }
    if (strlen(pFileName) >= COR_MAX_FILENAME_LEN)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "clCorDataFrequentSave: File name is too large"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM));
    }


    /*memcpy(corData.fileName, (pFileName), sizeof(corData.fileName));*/
    memcpy(corData.fileName, (pFileName), strlen(pFileName)+1);
    /* corData.version   = CL_COR_VERSION_NO; */
	CL_COR_VERSION_SET(corData.version);
    corData.operation = COR_DATA_FREQ_SAVE;
    corData.frequency = frequency;
    
    COR_CALL_RMD(COR_EO_PERSISTENCY_OP,
                 VDECL_VER(clXdrMarshallcorPersisInfo_t, 4, 0, 0),
                 &corData,
                 sizeof(corData), 
                 VDECL_VER(clXdrUnmarshallcorPersisInfo_t, 4, 0, 0),
                 NULL,
                 NULL,
                 rc);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "clCorDataFrequentSave returns error,rc=%x",rc));
    }

    
    CL_FUNC_EXIT();
    return rc;
}
ClRcT VDECL(_CORNotifyGetAttrBits) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                        ClBufferHandleT  outMsgHandle)
{
	ClRcT             rc = CL_OK;
	ClCorMOIdT        moId;
 	ClCorClassTypeT   classId;
	ClCorMOClassPathT moClsPath;
	ClUint32T         attrCnt;
    ClCorAttrPathT    attrPath;
	ClCorAttrListT   *pAttrList = NULL;
    ClCorAttrBitsT    attBits = {{0}};
	ClVersionT version;

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("NTF", "ATB", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

    /* Adding the version related check */
	if((rc = clXdrUnmarshallClVersionT(inMsgHandle, &version )) != CL_OK)
	     return (rc);
	/* Client to Server Version Check */
	clCorClientToServerVersionValidate(version, rc);
    if(rc != CL_OK)
	{
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}

	if((rc = VDECL_VER(clXdrUnmarshallClCorMOIdT, 4, 0, 0)(inMsgHandle, &moId )) != CL_OK)
	     return (rc);

	 if((rc = VDECL_VER(clXdrUnmarshallClCorAttrPathT, 4, 0, 0)(inMsgHandle, &attrPath )) != CL_OK)
	     return (rc);
 
	 if((rc = clXdrUnmarshallClUint32T(inMsgHandle, &attrCnt )) != CL_OK)
	     return (rc);
	

        clCorMoIdToMoClassPathGet (&moId, &moClsPath);
        /* can not use wild card in moID when requesting specific attribute change */
	if ((moId.svcId == CL_COR_SVC_WILD_CARD) || (clCorDoesPathContainWildCard(&moClsPath)))
    	{
                 CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Can not use wild cards for class type/svcId \
		                                      when using a list of attribute Ids\n"));
        	CL_FUNC_EXIT();
        	return (CL_COR_SET_RC(CL_COR_NOTIFY_ERR_CANNOT_RESOLVE_CLASS));
    	}
/**
 * get DM Handle from given ClCorMOId
 */
ClRcT
moId2DMHandle(ClCorMOIdPtrT path,
              DMObjHandle_h dmh)
{
    ObjTreeNode_h obj;
    CORObject_h dmObj;

    CL_FUNC_ENTER();
    
    if(!path || !dmh)
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }
    memset(dmh,0,sizeof(DMObjHandle_t));
    obj = corMOObjGet(path);
    if(obj)
    {
        ClCorMOServiceIdT svcId=(path)->svcId;
        
        dmObj = obj->data;
        if(svcId!=CL_COR_INVALID_SRVC_ID)
        { 
            dmObj=corMSOObjGet(obj, svcId);
        } 

        if (dmObj != NULL && dmObj->dmObjH.classId != 0)
        {
            (dmh)->classId = dmObj->dmObjH.classId;
            (dmh)->instanceId = dmObj->dmObjH.instanceId;
        }
        else
        {
            clLogInfo("COR", "OBH", 
                    "The Dm object node doesn't exist. rc[0x%x]", CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID));
            return CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID);
        }
    } 
    else
    {
	    clLogInfo("COR", "OBJ", 
                "The object node doesn't exist in the object tree. rc [0x%x]", CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID));
	    return CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID);
    }

    CL_FUNC_EXIT();
    return CL_OK;
}
static ClRcT clCorDeltaDbContAdd(ClCorDeltaSaveKeyT *deltaDbKey, ClDBRecordT deltaDbData, ClUint32T dataSize)
{
	ClRcT	rc = CL_OK;
	ClCorDeltaSaveKeyT *tempKey = deltaDbKey;
	ClCorDeltaContDataT *tempCont = clHeapCalloc(1, sizeof(ClCorDeltaContDataT));

    CL_ASSERT(tempCont != NULL);

    tempCont->data = deltaDbData;
    tempCont->dataSize = dataSize;

    if( tempKey == NULL || tempCont->data == NULL)
    {
		clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
				CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
		return CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
    }

    rc = clCntNodeAdd(gCorDeltaSaveKeyTable, (ClCntKeyHandleT) tempKey, (ClCntDataHandleT) tempCont , NULL);
    if(CL_OK != rc)
    {
        if (CL_GET_ERROR_CODE(rc) == CL_ERR_DUPLICATE)
            rc = CL_OK;
        else
            CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "Could not add node in the Delta Save Key Table", rc);    

        clHeapFree(tempCont);
    }  
	
	return rc;
}
ClRcT _clCorNodeNameToMoIdGet(ClNameT *nodeName, ClCorNodeDataPtrT *dataNode)
{
    ClRcT rc = CL_OK;
    ClCntNodeHandleT nodeHandle = 0;
    ClNameT *tempName = NULL;

	if(nodeName == NULL)
		return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);

    /* Get the data from the hash table */

    CL_DEBUG_PRINT(CL_DEBUG_TRACE,(" Node find for node Name  %s", nodeName->value));

    /* Do the node find and get the node handle for a particular node name. Now walk all the 
     * node for that particular node handle type.
     */
    rc = clCntNodeFind(nodeNameToMoIdTableHandle, (ClCntKeyHandleT)nodeName, &nodeHandle);   
    if(CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Failed to get the node Handle for the Node Name %s. rc [0x%x]", nodeName->value, rc));
        return rc;
    }

    while(nodeHandle != 0)
    {
        rc = clCntNodeUserKeyGet(nodeNameToMoIdTableHandle, nodeHandle, (ClCntKeyHandleT *) &tempName);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to get the user key from the node handle. rc[0x%x]", rc));
            break;
        }

        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Got the Nodename %s", tempName->value));
        rc = clCntNodeUserDataGet(nodeNameToMoIdTableHandle, nodeHandle, (ClCntDataHandleT *)dataNode);
        if(rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to get the user data from the node handle. rc [0x%x]", rc));
            break;
        }

        if((strcmp (nodeName->value, (*dataNode)->nodeName.value)) == 0)
        {
            CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Got the MoId for a Node Name %s", (*dataNode)->nodeName.value));
            return CL_OK;
        } 
        
        rc = clCntNextNodeGet(nodeNameToMoIdTableHandle, nodeHandle, &nodeHandle);  
        if(rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Failed to get the next node handle. rc[0x%x]", rc));
            break;
        }
    }

    if(CL_OK != rc)
        CL_COR_RETURN_ERROR(CL_DEBUG_TRACE, "Could not get MOId from the node name", rc);    
    return CL_OK;
}
/* happens only once during the booting of the system */
ClRcT clCorMOIdNodeNameMapAdd(ClCorMOIdPtrT pMoId, ClNameT *nodeName)
{
    ClRcT rc;
    /* Add the mapping in both the hash tables */
    /* In this table key is node Name and value is MoId */
    /* allocate MoId first */
    ClCorMOIdPtrT keyMoId = clHeapAllocate(sizeof(ClCorMOIdT));
	ClNameT		  *dataNodeName  = clHeapAllocate (sizeof(ClNameT));
	ClNameT		  *keyNodeName  = clHeapAllocate (sizeof(ClNameT));
    ClCorNodeDataPtrT dataNode = clHeapAllocate(sizeof(ClCorNodeDataT));
    if(dataNode == NULL)
    { 
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to allocate Node Data")); 
        return CL_COR_SET_RC(CL_COR_ERR_NO_MEM) ;
    }
    memset(&dataNode->nodeName, 0, sizeof(ClNameT));
    dataNode->pMoId = clHeapAllocate(sizeof(ClCorMOIdT));

    if( keyMoId == NULL || dataNodeName == NULL || dataNode->pMoId == NULL || keyNodeName == NULL)
    {
		clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
				CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
		return CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
    }

    memcpy(keyMoId, pMoId, sizeof(ClCorMOIdT));
    memcpy(dataNodeName, nodeName, sizeof(ClNameT));
    memcpy(dataNode->pMoId, pMoId, sizeof(ClCorMOIdT));
    memcpy(&dataNode->nodeName, nodeName, sizeof(ClNameT));
    memcpy(keyNodeName, nodeName, sizeof(ClNameT));

    rc = clCntNodeAdd(nodeNameToMoIdTableHandle, (ClCntKeyHandleT) dataNodeName, (ClCntDataHandleT )dataNode , NULL);
    
    if(CL_OK != rc)
        CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "Could not add node in nodeNameToMoIdHandle", rc);    
    
    /* MOID to Node Name map - In this table key is MOId and value is node name   */
    rc = clCntNodeAdd(moIdToNodeNameTableHandle, (ClCntKeyHandleT) keyMoId, (ClCntDataHandleT)keyNodeName, NULL);

    if(CL_OK != rc)
        CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "Could not add node in moIdToNodeNameHandle", rc);    
    
    return CL_OK;
}
ClRcT clCorAmfMoIdGet(const ClCharT *name,
                      ClAmsEntityTypeT type,
                      ClCorMOIdT *pMoId)
{
    ClAmsEntityT entity = {0};
    ClBufferHandleT msg = 0;
    ClRcT rc = CL_OK;
    ClVersionT version = {'B', 0x1, 0x1};
    ClCharT *data = NULL;
    ClUint32T dataLen = 0;
    ClCorObjectHandleT objHandle;

    if(!name || !pMoId) return CL_COR_SET_RC(CL_ERR_INVALID_PARAMETER);

    if(!mgmtHandle)
    {
        rc = clAmsMgmtInitialize(&mgmtHandle, NULL, &version);
        if(rc != CL_OK) return rc;
    }

    entity.type = type;
    clNameSet(&entity.name, name);
    ++entity.name.length;
    rc = clAmsMgmtEntityUserDataGetKey(mgmtHandle, &entity, &entity.name, &data, &dataLen);
    if(rc != CL_OK)
    {
        clLogError("FLT", "REPAIR", "Entity data get for [%s] returned [%#x]",
                   entity.name.value, rc);
        goto out_free;
    }
    rc = clBufferCreate(&msg);
    CL_ASSERT(rc == CL_OK);
    rc = clBufferNBytesWrite(msg, (ClUint8T*)data, dataLen);
    CL_ASSERT(rc == CL_OK);
    
    rc = VDECL_VER(clXdrUnmarshallClCorMOIdT, 4, 0, 0)(msg, pMoId);
    CL_ASSERT(rc == CL_OK);
    
    clBufferDelete(&msg);

    clLogNotice("COR", "AMF", "MOID for faulty entity [%s] ", entity.name.value);
    clCorMoIdShow(pMoId);
    
    /*
     * Validating moid
     */
    rc = clCorObjectHandleGet(pMoId, &objHandle);
    CL_ASSERT(rc == CL_OK);

    out_free:
    if(msg) clBufferDelete(&msg);
    if(data) clHeapFree(data);

    return rc;
}
/**
 *  Convert class IDs into class idx within a ClCorMOId.
 *
 *  This routine walks through all the valid entries in a ClCorMOId and
 * converts class ids into corresponding class index. Class
 * index represents the index of the class in ClCorMOId tree node array.
 * Note that this conversion is done "in-place", i.e., input ClCorMOId is
 * changed to have idx instead of class ID.
 *
 *  @param moId  - ClCorMOId to convert.
 *
 *  @returns CL_OK  - Success<br>
 *           CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) or CL_COR_SET_RC(CL_COR_ERR_INVALID_CLASS) on error.
 */
ClRcT 
corMOTreeClass2IdxConvert(ClCorMOIdPtrT moId)
{
    int i;
    ClRcT rc;
    ClCorMOClassPathT path;

    CL_FUNC_ENTER();
    
    if(!moTree)
      return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    
    if (moId == NULL)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    /* convert moId to corPath */
    rc = clCorMoIdToMoClassPathGet(moId, &path);
    if(rc == CL_OK)
      {
        if((rc = mArrayId2Idx(moTree, (ClUint32T *)path.node, path.depth))!=CL_OK)
          {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOTreeClassIdxGet failed rc => [0x%x]", rc));
          }
        else
          {
            /* copy the corPath indexes to ClCorMOId */
            for(i=0;(i<moId->depth) && (i < CL_COR_HANDLE_MAX_DEPTH);i++)
              {
                moId->node[i].type=path.node[i];
              }
          }
      }

    CL_FUNC_EXIT();
    return(rc);
}
/**
 *  Return the MO Class handle associated with the COR Path.
 *
 *  This API returns the MO Class handle associated with the 
 *  COR Path.
 * 
 *  @param moPath         MO path to the MO class
 *  @param moClassHandle   Reference to memory, where moClassHandle is returned
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH)	when the path specified is invalid
 *    CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_USR_BUF)	when got error while obtaining handle of the class in MO tree
 *
 */
ClRcT 
corMOClassHandleGet(ClCorMOClassPathPtrT moClassPath, 
                    CORMOClass_h* moClassHandle)
{
    
    if ((moClassPath == NULL) || (moClassHandle == NULL))
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOClassHandleGet: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    
    if (clCorMoClassPathValidate(moClassPath) != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to validate the moClassPath argument"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH));
      }
    
    if (moClassHandle)
      {
        *moClassHandle = corMOTreeFind(moClassPath);

        if (!*moClassHandle)
          {
            CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "Failed to get MO Class handle from tree node"));
            return(CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_USR_BUF));
          } else
            {
              CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "\nGot MO Class Handle, 0x%08x", 
                                    *((unsigned int *)moClassHandle)));
            }
      }
    
    CL_FUNC_EXIT();
    return(CL_OK);
}
/** 
 * Set the current moId path.
 * 
 * Set the current moId path for the caller EO. 
 *
 *  @param moIdH: path to set. This could be
 *   relative or absolute. If it is relative, it is
 *   appended to the current path. If this is absolute
 *   current path is replace by it.
 * 
 *  @returns CL_OK on successs.
 * 
 */
ClRcT
clCorMoIdCd(ClCorMOIdPtrT moIdH)
{
    ClRcT rc = CL_OK;
    ClCorMOIdPtrT pwd = 0;
    clEoExecutionObjT* eoObj = NULL;

    CL_FUNC_ENTER();
    

    if (moIdH == NULL)
    {
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }

    rc = clEoMyEoObjectGet (&eoObj);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("\n clEoMyEoObjectGet failed, rc = %x \n", rc));
        return rc;
    }

    if ((rc = clEoPrivateDataGet(eoObj,
                            CL_EO_COR_SERVER_COOKIE_ID,
			    (void **)&pwd)) != CL_OK) 
    {
        CL_FUNC_EXIT();
        return (rc);
    }

    if (moIdH->qualifier == CL_COR_MO_PATH_RELATIVE)
    {
     /* if the new path is relative, concatenate with pwd */
         rc = clCorMoIdConcatenate(pwd, moIdH, 0); 
    } 
    else 
    {
        *pwd = *moIdH;
    }

    CL_FUNC_EXIT();
    return (rc);
}
/**
 * Get the current moId path.
 * 
 * Get the current moId path from the caller's EO context. 
 *
 *  @param moIdH: [OUT] current path is returned here.
 *                Caller allocate the memory for the moId.
 * 
 *  @returns CL_OK on successs.
 * 
 */
ClRcT
clCorMoIdPwd(ClCorMOIdPtrT moIdH)
{
    ClRcT rc = CL_OK;
    ClCorMOIdPtrT pwd;
    clEoExecutionObjT* eoObj = NULL;


    CL_FUNC_ENTER();
    

    if (moIdH == NULL)
    {
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }
    rc = clEoMyEoObjectGet (&eoObj);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("\n clEoMyEoObjectGet failed, rc = %x \n", rc));
        return rc;
    }

    if ((rc = clEoPrivateDataGet(eoObj,
                            CL_EO_COR_SERVER_COOKIE_ID,
			    (void **)&pwd)) != CL_OK) 
    {
        CL_FUNC_EXIT();
        return (rc);
    }

  /* 
   * pwd is either CL_COR_MO_PATH_ABSOLUTE or 
   * CL_COR_MO_PATH_RELATIVE_TO_BASE. It can never be
   * CL_COR_MO_PATH_RELATIVE!!!
   */
    CL_ASSERT (pwd->qualifier != CL_COR_MO_PATH_RELATIVE) 

    *moIdH = *pwd;

    CL_FUNC_EXIT();
    return (rc);
}
/**
 *  get the DM Handle from the given object handle
 */
ClRcT
objHandle2DMHandle(ClCorObjectHandleT oh,
                   DMObjHandle_h dmh)
{
    ClRcT rc = CL_OK;
    ClCorMOIdT path; 

    CL_FUNC_ENTER();
    if(!dmh)
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }

    rc = clCorObjectHandleToMoIdGet(oh, &path, NULL);
    if (rc != CL_OK)
    {
        clLogError("OBJ", "DMH", "Failed to get the moId from object handle. rc [0x%x]", rc);
        return rc;
    }

    rc = moId2DMHandle(&path, dmh);
    if (rc != CL_OK)
    {
        clLogError("OBJ", "DMH", "Failed to get the DM handle from the object handle. rc [0x%x]", rc);
        return rc;
    }

#if 0
    if((ret=corOH2MOIdGet((COROH_h)(oh).tree, &path))==CL_OK)
      { 
         ret=moId2DMHandle(&path, dmh);
      }
#endif

    CL_FUNC_EXIT();
    return rc;
}
/** 
 * Compute size for the given class.
 *
 * API to compute size for all the class definitions. This function is
 * used by hashtable
 *
 *  @param this       object handle
 *  @param 
 * 
 *  @returns 
 *    ClRcT  CL_OK on success <br>
 *     CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) on null parameter.
 *
 *  @todo      need to fix the order in which its initialized.
 *
 */
ClRcT
dmClassSize(CORHashKey_h   key, 
            CORHashValue_h classBuf, 
            void *         userArg,
            ClUint32T dataLength
            )
{
    CORClass_h tmp = 0;
    ClInt32T sz = 0;
    ClInt32T* val = 0;
    ClUint16T Id = 0;
    ClUint16T* attrIdx = &Id;
    ClRcT rc = CL_OK;

    CL_FUNC_ENTER();

    if(!classBuf)
      {
        CL_FUNC_EXIT();  
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
      }

    tmp = (CORClass_h) classBuf; 
    if(tmp->size < 0) 
      {
        /* compute the full size */
        clLogDebug("DM", "ATR", "Computing class size for class id : [0x%x]", tmp->classId);

        val = &sz;
        rc = dmClassAttrWalk(tmp, NULL, dmClassAttrSize, (Byte_h*) &val);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Class Attr Walk failed. Failed to compute the size of the attributes. rc [0x%x]", rc));
            CL_FUNC_EXIT();
            return rc;
        }
		
        sz = (sz + sizeof(ClWordT)-1) & ~(sizeof(ClWordT)-1);

   /* Assign indexes to attributes. To be used in compressed 
         * DM Object Handle */
        rc = dmClassAttrWalk(tmp,
   				NULL,
   				dmObjectAttrIndexSet,
   				(Byte_h*)&attrIdx);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Class Attr Walk failed. Failed to find the indexes of the attributes. rc [0x%x]", rc));
            CL_FUNC_EXIT();
            return rc;
        }

        tmp->size = sz;
        clLogDebug("DM", "ATR", "Size of the class [0x%x] is : [%d]", tmp->classId, tmp->size);

        /* initialize the objects vector */
        
        /* todo: check the return value
         */
      }

    CL_FUNC_EXIT();
    return CL_OK;
}
/*
 *  TODO:
 * 1 - walk everything
 * 2 - MSO Walk
 * 3 - top down
 * 4 - bottom up 
 * make the return of the function to ClRcT, so it can be stopped
 */
ClRcT _clCorObjectWalk( ClCorMOIdPtrT cAddr, 
	    ClCorMOIdPtrT           cAddrWC,
        CORObjWalkFP            fp,
        ClCorObjWalkFlagsT      flags,
        ClBufferHandleT         bufferHandle
)
{
    ClCorMOIdT tmpMOId;
    ClCorMOIdPtrT cookie = &tmpMOId;  
    ObjTree_t tmpTree;
    MArrayWalk_t tmpWalkDetails={0};
    MArrayWalk_h walkCookie = &tmpWalkDetails;
    ClRuleExprT* pRbeExpr = NULL;
    ClRcT rc = CL_OK;
    
    CL_FUNC_ENTER();

    /* todo: The cookie can be OH instead of ClCorMOId for optimizations
     */
    if(!objTree)
         return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      tmpTree = *objTree;

    /* do some validations to parameters */
    if(!fp)
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }
    
    if(cAddr && cAddr->depth == 0)
        cAddr = NULL;

    if(cAddrWC &&  cAddrWC->depth == 0)
        cAddrWC = NULL;

    if((flags > CL_COR_MSO_WALK_UP) || (flags < CL_COR_MO_WALK))
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
    }

    if(cAddr &&
       (((cAddr->svcId != CL_COR_INVALID_SVC_ID) &&
         ((flags == CL_COR_MO_WALK) || (flags == CL_COR_MO_WALK_UP))) ||
        ((cAddr->svcId < CL_COR_INVALID_SVC_ID || cAddr->svcId >= CL_COR_SVC_ID_MAX) &&
         ((flags == CL_COR_MSO_WALK) || (flags == CL_COR_MSO_WALK_UP)))))
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_SVC_ERR_INVALID_ID);
    }

    /* set the root of the walk here */
    if(cAddr)
    {
        if(cAddr->depth>0)
          {
            tmpTree.root = corObjTreeNodeFind(objTree, cAddr);
          }
        *cookie = *cAddr; 
    }
    else
    {
        clCorMoIdInitialize(cookie);
    }
     
    if(tmpTree.root)
    {
		int idx = 0;
        switch(flags)
        {
            case CL_COR_MO_SUBTREE_WALK:
                tmpWalkDetails.flags = CL_COR_MO_SUBTREE_WALK;
                tmpWalkDetails.fpNode = (MArrayNodeFP)fp;
                tmpWalkDetails.fpData = 0;
            break;

            case CL_COR_MO_WALK:
            case CL_COR_MO_WALK_UP:
                tmpWalkDetails.fpNode = (MArrayNodeFP)fp;
                tmpWalkDetails.fpData = 0;
            break;

            case CL_COR_MSO_SUBTREE_WALK:
                tmpWalkDetails.flags = CL_COR_MSO_SUBTREE_WALK;
                tmpWalkDetails.fpNode = 0;
                tmpWalkDetails.fpData = (MArrayNodeFP)fp;
                break;

            case CL_COR_MSO_WALK:
            case CL_COR_MSO_WALK_UP:
                tmpWalkDetails.fpNode = 0;
                tmpWalkDetails.fpData = (MArrayNodeFP)fp;
                break;

            default:
                return CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
        } 

        if (bufferHandle)
            tmpWalkDetails.pMsg  =  &bufferHandle;

        tmpWalkDetails.flags =  flags;
        tmpWalkDetails.cookie = (void **) &cookie;

        if(cAddrWC && corMOIdExprCreate(cAddrWC,&pRbeExpr) != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("MOId to Expression Creation Failed : [0x%x]",rc));
            return rc;
        }

        tmpWalkDetails.expr = pRbeExpr;

        if(cookie && cookie->depth)
            idx = clCorMoIdToInstanceGet(cookie);

        mArrayWalk(idx,
                   &tmpTree, 
                   _corObjWalkFun, 
                   _corObjWalkFun, 
                   (void **)&walkCookie,
                   rc);
    }

    if(pRbeExpr)
    	clRuleExprDeallocate(pRbeExpr);

    CL_FUNC_EXIT();
    return 0;
}
/** 
 * Delete a class from class handle.
 *
 * API to dmClassByHandleDelete <Deailed desc>. 
 *
 *  @param this       object handle
 *  @param 
 * 
 *  @returns 
 *    ClRcT  CL_OK on success <br>
 *     CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) on null parameter.
 *
 *  @todo      
 *
 */
ClRcT
dmClassByHandleDelete(CORClass_h classHandle
                      )
{
    ClRcT ret = CL_OK;
    CORClass_h tmp = 0;

    CL_FUNC_ENTER();

    if((!classHandle) || (!dmGlobal))
      {
        CL_FUNC_EXIT();  
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassDelete (Class:%04x)", 
                          classHandle->classId));


    /* check if instances are there and also base classes
     * by default cannot be deleted, they may be in other
     * inherited classes.
     */
    if (COR_CLASS_IS_BASE(*classHandle))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassDelete (Class:%04x) [Class is base]", classHandle->classId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_IS_BASE);
    }
    else if(classHandle->objCount == 0 && 
           (classHandle->moClassInstances == 0))
      {
        
        /* get the handle to the parent class */
        HASH_GET(dmGlobal->classTable,classHandle->superClassId, tmp);
        if(tmp)
        {
            tmp->noOfChildren--;
            if(tmp->noOfChildren == 0)
                COR_CLASS_RESETAS_BASE(*tmp);
        }
        /* now we can remove from hash table & free it 
         */
        HASH_REMOVE(dmGlobal->classTable, classHandle->classId);
        /* free the attribute list hashtable and the elements in
         * the vector 
         */
        HASH_FREE(classHandle->attrList);
        COR_LLIST_FREE(classHandle->objFreeList);

        corVectorRemoveAll(&classHandle->attrs);
        /* nothing to remove in the objects vector */
        clHeapFree(classHandle);
      } 
    else 
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassDelete (Class:%04x) [Instances present]", 
                              classHandle->classId));
        
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT);
      }
    
    CL_FUNC_EXIT();
    return (ret);
}
/** 
 *  Class Type create API.
 *
 *  Creates a new class type with the given information like class id,
 *  number of attributes, max and minimum instances for the class.
 *  NOTE: What happens in case of different versions?? need to figure
 *  out.
 *
 *  @param id            class id
 *  @param nAttrs        Number of attributes in class.
 *
 *  @returns 
 *    CORClass_h   (non-null) valid class handle
 *      null(0)    on failure.
 * 
 */
ClRcT
dmClassCreate(ClCorClassTypeT id,
              ClCorClassTypeT inhId)
{
    CORClass_h tmp = 0;
    CORClass_h tmp1 = 0;
    ClRcT ret = CL_OK;

    CL_FUNC_ENTER();

    if(!dmGlobal)
    {
        CL_FUNC_EXIT();  
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassCreate (Class:%04x, Inh:%04x)", id, inhId));
    
    /* check if id & inhId is already present 
     */
    HASH_GET(dmGlobal->classTable, id, tmp);
    if(inhId > 0) 
    {
        HASH_GET(dmGlobal->classTable, inhId, tmp1);
    }
    
    if(tmp) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassCreate (Class:%04x, Inh:%04x) [Class present]", id, inhId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_PRESENT);
    } 
    else if(tmp1 == 0 && inhId > 0) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassCreate (Class:%04x, Inh:%04x) [Superclass unknown]", id, inhId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT);
    } 
    else 
    {
        /* Create the new class
         */
        tmp = (CORClass_h) clHeapAllocate(sizeof(CORClass_t));
        if(tmp != 0) 
        {
            /* init stuff here */
            tmp->classId = id;
            tmp->superClassId = inhId; 
            tmp->size = -1;
            tmp->version.releaseCode = CL_RELEASE_VERSION;
            tmp->version.majorVersion = CL_MAJOR_VERSION;
            tmp->version.minorVersion = CL_MINOR_VERSION;
            tmp->flags = 0;
            tmp->moClassInstances = 0;

            if (CL_OK != (ret = HASH_CREATE(&tmp->attrList)))
            { 
                  clHeapFree(tmp);
                  CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to create hash table for Attributes [rc 0x%x]", ret));
                  CL_FUNC_EXIT();  
                  return (ret);
            }
        
            if (CL_OK != (ret = COR_LLIST_CREATE(&tmp->objFreeList)))
            {
                clHeapFree(tmp);
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to create hash table for free objects [rc 0x%x]", ret));
                CL_FUNC_EXIT();
                return (ret);
            }

            tmp->nAttrs = 0;
            tmp->noOfChildren = 0;
            tmp->recordId = 1;
            tmp->objCount = 0;
            tmp->objBlockSz = COR_OBJ_DEF_BLOCK_SIZE;

            /* init the vector, check the return value
             * and remove class/hashtable
             */
            if (CL_OK != (ret = corVectorInit(&tmp->attrs, 
                          sizeof(CORAttr_t),
                          COR_CLASS_DEF_BLOCK_SIZE)))
            {
                HASH_FREE(tmp->attrList);
                COR_LLIST_FREE(tmp->objFreeList);
                clHeapFree(tmp);
    	        CL_FUNC_EXIT();  
     	        return (ret);
	        }

            /* add the newly created class to the class table */
            if (CL_OK != (ret = HASH_PUT(dmGlobal->classTable, id, tmp)))
	        {
              corVectorRemoveAll(&tmp->attrs);
              HASH_FREE(tmp->attrList);
              COR_LLIST_FREE(tmp->objFreeList);
              clHeapFree(tmp);
       	      CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to add class in Data Manager [rc 0x%x]", ret));
    	      CL_FUNC_EXIT();  
     	      return (ret);
	        }
            /* declare the inh class as base class */
            if(inhId > 0) 
            {
                tmp1->noOfChildren++;
                COR_CLASS_SETAS_BASE(*tmp1);
            }
        } 
        else 
        {
	        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
				CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
                CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, (CL_COR_ERR_STR_MEM_ALLOC_FAIL)); 
            ret = CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
        }
    }

    CL_FUNC_EXIT();  
    return (ret);
}
ClRcT 
_clCorNextMOGet(ClCorObjectHandleT stOH, 
           ClCorClassTypeT Id,
	   ClCorServiceIdT  svcId,
           ClCorObjectHandleT *nxtOH
           )
{
    ClRcT rc = CL_OK;
    ClCorMOIdPtrT tmpMOId;
    ObjTreeNode_h node;
    CORObject_h   svcObjH;

    ClUint8T clsFound = 0;
    ClUint8T svcFound = 0;

      /* check if objtree is present */
      if(!objTree)
         return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    /*Steps
     * 1. Get the next node from given handle.
     *     if given handle is empty, get first node of tree.
     * 2. Apply the filter on the obtained node's moId.
     * 3. Repeat step 2 unless filtering criterion passes 
     *     OR we reach at last node in tree.
     */
    if(CL_OK != (rc = clCorMoIdAlloc(&tmpMOId)))
       {
       	    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to Allocate MoId") );
       	    return (rc);   
       }	       

    if(CL_COR_OBJ_HANDLE_ISNULL(stOH))
    {
      node = corObjTreeNextNodeFind(objTree, tmpMOId);
    }
    else
    {
       if(CL_OK != (rc = corOH2MOIdGet((COROH_h)&stOH.tree, tmpMOId)))
       {
	    clCorMoIdFree(tmpMOId);
       	    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Invalid Object Handle.") );
       	    return (CL_COR_SET_RC(CL_COR_ERR_INVALID_HANDLE));   
       }	       
       node = corObjTreeNextNodeFind(objTree, tmpMOId);
    }

    /* Apply Filter */
    while(node && !(clsFound && svcFound))
    {
       if(Id == CL_COR_CLASS_WILD_CARD ||
	              tmpMOId->node[tmpMOId->depth-1].type == Id)
	   { 
 	       clsFound = 1;
	       if(svcId == CL_COR_SVC_WILD_CARD ||
    			   (svcObjH = corMSOObjGet(node, svcId))?!COR_OBJECT_ISNULL(*svcObjH):0)
	       {
		 svcFound = 1;
		 break;
	       }
	       /* reset clsFound*/
	       clsFound = 0;
	   }
      /* Filter criterion failed -  Get next object. */	   
      node = corObjTreeNextNodeFind(objTree, tmpMOId);
    }
 
    /* Found the node. */
    if(node)
    { 
	/* @todo: do we need to fill dm part of handle ? */     
        if(CL_OK != (rc = corMOId2OHGet(tmpMOId, (COROH_h)nxtOH->tree)))
	{
	   /* Critical Error.
	    * MoId contents have been corrupted.
	    */
	   clCorMoIdFree(tmpMOId);
           CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
	  	       ( "MoId contents are corrupted. Error[0x%x]",rc));
       	   return (rc);   
	}
    }else
        {  /* Node is not found
	    Reset handle to NULL
	    */
	  CL_COR_OBJ_HANDLE_INIT(*nxtOH);
	}  
   clCorMoIdFree(tmpMOId);
   return (rc);
}
ClRcT VDECL(_corObjectWalkOp) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
    ClRcT rc = CL_OK;
    corObjFlagNWalkInfoT* pData = NULL;
    CL_FUNC_ENTER();

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("OBW", "EOF", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

    pData = clHeapAllocate(sizeof(corObjFlagNWalkInfoT));
    if(!pData)
    {
          clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, gCorClientLibName,
                    CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
           CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
           return (CL_COR_SET_RC(CL_COR_ERR_NO_MEM));
    }

    if((rc = VDECL_VER(clXdrUnmarshallcorObjFlagNWalkInfoT, 4, 0, 0)(inMsgHandle, (void *)pData)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to Unmarshall corObjFlagNWalkInfoT"));
            clHeapFree(pData);
        return rc;
    }

	clCorClientToServerVersionValidate(pData->version, rc);
    if(rc != CL_OK)
	{
		clHeapFree(pData);	
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}

    switch(pData->operation)
    {
        case COR_OBJ_WALK_DATA_GET:
            clOsalMutexLock(gCorMutexes.gCorServerMutex);

#if 0            
            objHdlCount = 0;
            rc = _corObjectCountGet(&iCount);
            pObjHdlList = (char *) clHeapAllocate(iCount*sizeof(ClCorObjectHandleT));
	   	    if(pObjHdlList == NULL)
	        {
       			 clHeapFree(pData);
            	 clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
			  	 clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
					CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
 				 CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
				 return CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
	    	}

            clLogTrace("OBW", "EFN", "Going for the object walk now");
#endif

            rc = _clCorObjectWalk(&pData->moId, &pData->moIdWithWC, _corObjHdlListGet, pData->flags, outMsgHandle);
            if (CL_OK != rc)
            {
                clLogError("OBW", "EFN", 
                        "Failed to do the object walk on server. rc[0x%x]", rc);
            }
#if 0
            else
            {
	            rc = clBufferNBytesWrite(outMsgHandle, (ClUint8T *)pObjHdlList,
            	                (ClUint32T)objHdlCount * sizeof(ClCorObjectHandleT));
                if (CL_OK != rc)
                    clLogError("OBW", "EFN", 
                            "Failed to write the object walk information into the out buffer. rc[0x%x]", rc);
            }

            clLogTrace("OBW", "EFN", "Done with the object walk");

            clHeapFree(pObjHdlList);
#endif
            clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
        break;
        case COR_OBJ_SUBTREE_DELETE:
           clOsalMutexLock(gCorMutexes.gCorServerMutex);
           rc = _clCorSubTreeDelete(pData->moId);
           clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
        break;
        default:
             CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "INVALID OPERATION, rc = %x", rc) );
             rc = CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
        break;
    }
   
    CL_FUNC_EXIT();
    clHeapFree(pData);
    return rc;
}
ClRcT clCorLogicalSlotToMoIdGet(ClUint32T logicalSlot, ClCorMOIdPtrT  pMoId)
{
	return CL_COR_SET_RC(CL_COR_ERR_NOT_SUPPORTED);
}
ClRcT clCorMoIdToLogicalSlotGet(ClCorMOIdPtrT pMoId, ClUint32T* logicalSlot)
{
	return CL_COR_SET_RC(CL_COR_ERR_NOT_SUPPORTED);
}
/**
 *  Create the specified Managed Object type.
 *
 *  API to create a new MO type and add it to the meta structure in
 *  COR. 'class' specified should be already defined.
 * 
 *  @param moPath        		Path of the class in MO Tree. e.g. /chassis/blade
 *  @param maxInstances       	Max imum instances of this MO class type that can be created
 *  @param moClassHandle 	[out] Handle to the class type created
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH) when path specified is invalid
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT) when class definition for the class is not present
 *    CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE) when addition to MO Tree fails
 *
 */
ClRcT 
_corMOClassCreate(ClCorMOClassPathPtrT moClassPath, 
                 ClInt32T maxInstances, 
                 CORMOClass_h* moClassHandle
                 )
{
    ClCorClassTypeT moClassType;
     CORClass_h corClassHandle;
    ClRcT  rc = CL_OK;

    CL_FUNC_ENTER();
    
    if(!moTree)
      return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "Max instances %d", (ClUint32T)maxInstances));

    if ((moClassPath == NULL) || (moClassHandle == NULL))
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    if ( ( 0 > maxInstances ) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate: Negative Max Instance"));
        CL_FUNC_EXIT();
        return (CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM));
    }
    
    
    if (clCorMoClassPathValidate(moClassPath) != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to validate the moClassPath argument"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH));
      }
    
    moClassType = clCorMoClassPathToMoClassGet(moClassPath);
    
    /* Validate with data manager, the final class ID */
    if (dmClassIsPresent(moClassType) != CL_TRUE)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Invalid class type specified"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT));
      }

	/*Get the DM class first*/
	corClassHandle = dmClassGet(moClassType);
	if(NULL != corClassHandle)
		{
		corClassHandle->moClassInstances++;
		}
    
    rc = corMOTreeAdd(moTree, moClassPath, maxInstances);
    if (rc != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to Add node by path"));
        return(CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE));
      }
    
    if (moClassHandle)
      *moClassHandle = corMOTreeFind(moClassPath);
    
    CL_FUNC_ENTER();
    return(CL_OK);
}
/**
 *  Delete the last node in the MO hierarchy.
 *
 *  API to delete the class type specified if there are no instances
 *  in the COR.  NOTE: This API shall delete the class specified in
 *  the ClCorMOClassPath and the subtree of classes, including the service
 *  class ids.
 *                                                                        
 *  @param 	moPath  path to the class to be deleted from MO Tree
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH)	when path specified is not valid
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT)	When class instance is present you can not delete class.
 *    CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_DEL_NODE)	When failed to delete node from MO Tree
 *
 */
ClRcT 
_corMOClassDelete(ClCorMOClassPathPtrT moClassPath)
{
    ClRcT rc;
    ClCorClassTypeT moClassType;
	MOTreeNode_h node;
	ClUint32T numChildNode; 
	CORClass_h corClassHandle;
	

    CL_FUNC_ENTER();
    
    if (moClassPath == NULL)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassDelete: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    if (clCorMoClassPathValidate(moClassPath) != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to validate the moClassPath argument"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH));
      }

#ifdef DEBUG
    CL_DEBUG_PRINT(CL_DEBUG_INFO, ( "Delete MOTree object: "));
    clCorMoClassPathShow(moClassPath);
#endif

    moClassType = clCorMoClassPathToMoClassGet(moClassPath);
#if 0
    /* This check is not required. In case if a COR class is used by TWO
  	MOs, We won't be able to delete one MO even if instance of other
  	is present. 

  	Instead we need to look into MO Class Handle to determine how many
  	objects of MO are present*/
  	
    moClassType = clCorMoClassPathToMoClassGet(&nCorPath);
    if ( dmClassInstanceCountGet(moClassType) > 1 )
    {
        CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class instance already present or is a base-class"));
        CL_FUNC_EXIT();
        return (CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT));
    }
#endif

   	node = corMOTreeFind(moClassPath);
	if(NULL == node)
	{
       	CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Could not find node information in the tree."));
       	CL_FUNC_EXIT();
       	return (CL_COR_SET_RC(CL_COR_MO_TREE_ERR_NODE_NOT_FOUND));
	}
	
	if( ((_CORMOClass_h)node->data)->instances > 0)
		{
		/* Object Instances present */
		CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class instance already present"));
		CL_FUNC_EXIT();
		return (CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT));
		}
	
	numChildNode = ( (_CORMOClass_h)(node->data) )->numChildren;
	if(numChildNode > 1)
	{
       	CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class has children classes. Deletion is not possible."));
       	CL_FUNC_EXIT();
       	return (CL_COR_SET_RC(CL_COR_MO_TREE_ERR_CHILD_CLASS_EXIST));
	}
    rc = corMOTreeDel(moClassPath);
    if ( rc != CL_OK )
	{
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to delete node by path"));
        return rc;
	}
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "\nDeleted MO Class node from hierarchy"));

		/*Get the DM class first*/
	corClassHandle = dmClassGet(moClassType);
	if(NULL != corClassHandle)
		{
		corClassHandle->moClassInstances--;
                                
		}
    CL_FUNC_EXIT();
    return(CL_OK);
}
ClRcT  VDECL(_corMOTreeClassOpRmd) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
    ClRcT rc = CL_OK;
    corClassDetails_t *pClassInfo = NULL;
    CORMOClass_h moClassHandle;
    CORMSOClass_h msoClassHandle;

    CL_FUNC_ENTER();

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("MOT", "EOF", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }
    
    pClassInfo = clHeapAllocate(sizeof(corClassDetails_t));
    if(pClassInfo == NULL) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }

	if((rc = VDECL_VER(clXdrUnmarshallcorClassDetails_t, 4, 0, 0)(inMsgHandle, (void *)pClassInfo)) != CL_OK)
	{
		clHeapFree(pClassInfo);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to Unmarshall corClassDetails_t "));
		return rc;
	}
    /* if((rc = clBufferFlatten(inMsgHandle, (ClUint8T **)&pClassInfo))!= CL_OK)
    {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to flatten the Message"));
                CL_FUNC_EXIT();
	        return rc;
    }*/	
    /* if(pClassInfo->version > CL_COR_VERSION_NO)
    {
		clHeapFree(pClassInfo);
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Version mismatch"));
        CL_FUNC_EXIT();
        return CL_ERR_VERSION_MISMATCH;
    }*/

	clCorClientToServerVersionValidate(pClassInfo->version, rc);
    if(rc != CL_OK)
	{
		clHeapFree(pClassInfo);	
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}
  
    switch(pClassInfo->operation)
    {
        case COR_CLASS_OP_CREATE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = _corMOClassCreate(&(pClassInfo->corPath), pClassInfo->maxInstances, &moClassHandle);
                if(rc != CL_OK)
                {
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
						CL_LOG_MESSAGE_1_MOCLASS_CREATE, rc);
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOClassHandleGet failure"));
                }
                else
                {
                	rc = _corMSOClassCreate(moClassHandle, pClassInfo->svcId,
                       	                pClassInfo->objClass, &msoClassHandle);
                    if(rc != CL_OK)
               			CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMSOClassCreate failure"));
                }

               	if(rc != CL_OK)
               	{
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
					CL_LOG_MESSAGE_1_MSOCLASS_CREATE, rc);
               		CL_FUNC_EXIT();
               		return rc;
                }
            }
            break;
        case COR_CLASS_OP_DELETE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = _corMOClassDelete(&(pClassInfo->corPath));
                if(rc != CL_OK)
                {
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
					CL_LOG_MESSAGE_1_MOCLASS_DELETE, rc);
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassDelete failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOClassHandleGet failure"));
                else
                {
                    rc = _corMSOClassDelete(moClassHandle, pClassInfo->svcId);
                    if(rc != CL_OK)
                        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMSOClassDelete failure"));
                }

                if(rc != CL_OK)
               	{
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
						CL_LOG_MESSAGE_1_MSOCLASS_DELETE, rc);
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            break;
        case COR_CLASS_OP_EXISTANCE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
                rc = corMSOClassHandleGet(moClassHandle, pClassInfo->svcId, &msoClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMSOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            break;
        case COR_CLASS_OP_CLASSID_GET:
            rc = _corMOPathToClassIdGet(&(pClassInfo->corPath), pClassInfo->svcId, &(pClassInfo->objClass));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMSOClassHandleGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        case COR_CLASS_OP_FIRSTCHILD_GET:
            rc = _clCorMoClassPathFirstChildGet(&(pClassInfo->corPath));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "_clCorMoPathFirstChildGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        case COR_CLASS_OP_NEXTSIBLING_GET:
            rc = _clCorMoClassPathNextSiblingGet(&(pClassInfo->corPath));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "_clCorMoPathNextSiblingGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        default:
			CL_DEBUG_PRINT(CL_DEBUG_ERROR,("MOClass Request Type %d", pClassInfo->operation));
            break;
    }

    if (pClassInfo->operation == COR_CLASS_OP_CREATE ||
            pClassInfo->operation == COR_CLASS_OP_DELETE)
    {
        if (gCorSlaveSyncUpDone == CL_TRUE)
        {
            ClRcT retCode = CL_OK;

            retCode = clCorSyncDataWithSlave(COR_EO_MOTREE_OP, inMsgHandle);
            if (retCode != CL_OK)
            {
                clLogError("SYNC", "", "Failed to sync data with slave COR. rc [0x%x]", rc);
                /* Ignore the error code. */
            }
        }
    }

    CL_FUNC_EXIT();
	clHeapFree(pClassInfo);
    return rc;
}
static ClRcT corAmfExtendedClassObjectCreate(const ClCharT *pExtendedClassName,
                                             ClAmsEntityT *pEntity,
                                             ClCorMOIdT *pChassisMoId,
                                             ClUint32T rankListCount,
                                             ClUint32T *pClassIndex,
                                             ClUint32T *pIndex)
{
    ClCorAttributeValueListT attrList = {0};
    ClCorClassTypeT classType = 0;
    ClCorMOIdT moId;
    ClRcT rc = CL_OK;
    ClUint32T i;
    ClUint32T classIndex = 0;

    if(!pExtendedClassName || !pEntity || !pChassisMoId || !pClassIndex || !pIndex)
        return CL_COR_SET_RC(CL_ERR_INVALID_PARAMETER);
    if(!rankListCount)
        return CL_OK;
    rc = corAmfExtendedClassAttributeListGet(pExtendedClassName, &attrList, &classType);
    if(rc != CL_OK)
        return rc;
    if(attrList.numOfValues != 2)
    {
        clLogError("COR", "AMF", "Expected [%d] keys but got [%d] keys in table [%s]",
                   2, attrList.numOfValues, pExtendedClassName);
        if(attrList.pAttributeValue)
        {
            clHeapFree(attrList.pAttributeValue);
            return CL_COR_SET_RC(CL_ERR_NOT_EXIST);
        }
    }
    classIndex = *pClassIndex;
    for(i = 0; i < rankListCount; ++i)
    {
        memcpy(&moId, pChassisMoId, sizeof(moId));
        rc = clCorMoIdAppend(&moId, classType, classIndex);
        CL_ASSERT(rc == CL_OK);
        rc = clCorObjectCreate(&sessionId, &moId, NULL);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "COR MO object create for entity [%s], table [%s] returned [%#x]",
                       pEntity->name.value, pExtendedClassName, rc);
            goto out_free;
        }
        rc = clCorMoIdServiceSet(&moId, CL_COR_SVC_ID_PROVISIONING_MANAGEMENT);
        CL_ASSERT(rc == CL_OK);
        attrList.pAttributeValue[0].bufferPtr = (ClPtrT)pIndex;
        attrList.pAttributeValue[0].bufferSize = (ClUint32T)sizeof(*pIndex);
        attrList.pAttributeValue[1].bufferPtr = (ClPtrT)&i;
        attrList.pAttributeValue[1].bufferSize = (ClUint32T)sizeof(i);
        rc = clCorObjectCreateAndSet(&sessionId, &moId, &attrList, NULL);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "Cor MSO object create for entity [%s], table [%s] returned [%#x]",
                       pEntity->name.value, pExtendedClassName, rc);
            goto out_free;
        }
        ++classIndex;
    }

    out_free:
    if(attrList.pAttributeValue)
    {
        clHeapFree(attrList.pAttributeValue);
    }
    *pClassIndex = classIndex;
    return rc;
}
ClRcT
clProvObjectCreate(ClCorMOIdPtrT pMoId, ClCorAttributeValueListPtrT attrList, ClCorObjectHandleT* pHandle)
{
    ClRcT rc = CL_OK;
    ClCorMOIdPtrT pTempMoId = NULL;
    ClCorObjectHandleT moHandle = NULL;
    ClCorObjectHandleT msoHandle = NULL;
    ClCorTxnSessionIdT tid = 0;
    ClCorAddrT provAddr = {0};

    CL_FUNC_ENTER();
    
    /* Create the MO object */
    if(NULL == pMoId)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("\nNULL parameter passed\n"));
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }

    rc = clCorMoIdClone(pMoId, &pTempMoId);
    if(CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed while cloning the MoId. rc[0x%x]", rc));
        CL_FUNC_EXIT();
        return rc;
    }

    rc = clCorMoIdServiceSet(pTempMoId, CL_COR_INVALID_SRVC_ID);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to set the service id of the MoId. rc [0x%x]", rc));
        clCorMoIdFree(pTempMoId);
        CL_FUNC_EXIT();
        return rc;
    }
    
    tid = 0;
    
    if (CL_OK != clCorObjectHandleGet(pTempMoId, &moHandle))
    {
        rc = clCorObjectCreate(&tid, pTempMoId, NULL);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to add MO object creation in txn. rc [0x%x]", rc));
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }        
    }
    else
        clCorObjectHandleFree(&moHandle);

    rc = clCorMoIdServiceSet(pTempMoId, CL_COR_SVC_ID_PROVISIONING_MANAGEMENT);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to set the service id of the MoId. rc [0x%x]\n", rc));
        clCorMoIdFree(pTempMoId);
        clCorTxnSessionFinalize(tid);
        CL_FUNC_EXIT();
        return rc;
    }

    if (CL_OK != clCorObjectHandleGet(pTempMoId, &msoHandle))
    {
        rc = clCorObjectCreateAndSet(&tid, pTempMoId, attrList, &msoHandle);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                ("Failed to add create and set for the MSO object in txn. rc [0x%x]", rc));
            clCorMoIdFree(pTempMoId);
            clCorTxnSessionFinalize(tid);
            CL_FUNC_EXIT();
            return (rc);
        }

        rc = clCorTxnSessionCommit(tid);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to commit the transaction. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            clCorTxnSessionFinalize(tid);
            CL_FUNC_EXIT();
            return rc;            
        }

        provAddr.nodeAddress = clIocLocalAddressGet();
        rc = clEoMyEoIocPortGet(&provAddr.portId);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to get the IOC port. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }
        
        rc = clCorOIRegister(pTempMoId, &provAddr);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to register the OI with COR. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }
    }
    
    clCorMoIdFree(pTempMoId);

    /* Assign the prov mso handle */
    *pHandle = msoHandle;

    CL_FUNC_EXIT();
    return (CL_OK);
}