SaAisErrorT saAmfComponentUnregister(SaAmfHandleT amfHandle,
                                     const SaNameT *compName,
                                     const SaNameT *proxyCompName)
{
    ClRcT rc;
    SaNameT compNameInternal = {0};
    SaNameT proxyCompNameInternal = {0};
    SaNameT *proxy = (SaNameT*)proxyCompName;
    
    if(!compName) return SA_AIS_ERR_INVALID_PARAM;
    
    clNameCopy((ClNameT*)&compNameInternal, (const ClNameT*)compName);

    if(proxyCompName)
    {
        clNameCopy((ClNameT*)&proxyCompNameInternal, 
                   (const ClNameT*)proxyCompName);
        proxy = &proxyCompNameInternal;
    }

    rc = clCpmComponentUnregister(amfHandle,
                                  (const ClNameT*)&compNameInternal,
                                  (const ClNameT*)proxy);

    return clClovisToSafError(rc);
}
/*
 * The following definition should ideally be in EoApi. 
 * Duplicating here for now.
 */
typedef enum{
    CL_EO_LIB_ID_OSAL,
    CL_EO_LIB_ID_MEM,
    CL_EO_LIB_ID_HEAP,
    CL_EO_LIB_ID_BUFFER,
    CL_EO_LIB_ID_TIMER,
    CL_EO_LIB_ID_IOC,
    CL_EO_LIB_ID_RMD,
    CL_EO_LIB_ID_EO,
    CL_EO_LIB_ID_RES,
    CL_EO_LIB_ID_POOL  =  CL_EO_LIB_ID_RES,
    CL_EO_LIB_ID_CPM,
    CL_EO_LIB_ID_MAX 
}ClEoLibIdT; 

typedef struct ClPubsEventInfo
{
    ClEventInitHandleT initHandle;
    ClEventChannelHandleT channelHandle;
    ClEventHandleT eventHandle;
} ClPubsEventInfoT; 

static ClPubsEventInfoT gPubsEventInfo;

static ClEoPayloadWithReplyCallbackT gClEvtPubsTestFuncList[] =
{
    (ClEoPayloadWithReplyCallbackT) NULL,                          /* 0 */
};

static ClRcT clPubsTriggerEvent(ClEoLibIdT libId, ClWaterMarkIdT wmId, ClUint32T wmValue, ClEoWaterMarkFlagT wmFlag)
{
    ClRcT rc = CL_OK;

    ClEventIdT eventId = 0;
    SaNameT publisherName = {sizeof(CL_EVENT_PUBLISHER_NAME)-1, CL_EVENT_PUBLISHER_NAME};

    ClEventPatternT patterns[5] = {{0}};

    ClEventPatternArrayT patternArray = {
        0,
        CL_SIZEOF_ARRAY(patterns),
        patterns 
    };

    rc = clEventAllocate(gPubsEventInfo.channelHandle, &gPubsEventInfo.eventHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventAllocate() failed [%#X]\n",rc);
        goto failure;
    }

    patterns[0].patternSize = strlen(CL_EO_NAME);
    patterns[0].pPattern = (ClUint8T *)CL_EO_NAME;
    
    patterns[1].patternSize = sizeof(libId);
    patterns[1].pPattern = (ClUint8T *)&libId;
    
    patterns[2].patternSize = sizeof(wmId);
    patterns[2].pPattern = (ClUint8T *)&wmId;
    
    patterns[3].patternSize = sizeof(wmFlag);
    patterns[3].pPattern = (ClUint8T *)&wmFlag;
    
    patterns[4].patternSize = sizeof(wmValue);
    patterns[4].pPattern = (ClUint8T *)(&wmValue);
    
    rc = clEventAttributesSet(gPubsEventInfo.eventHandle, &patternArray, 
            CL_EVENT_HIGHEST_PRIORITY, 0, &publisherName);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventAttributesSet() failed [%#X]\n",rc);
        goto event_allocated;
    }

    rc = clEventPublish(gPubsEventInfo.eventHandle, "Event Payload passed in endian neutral way", 
            sizeof("Event Payload passed in endian neutral way."), &eventId);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventPublish() failed [%#X]\n",rc);
        goto event_allocated;
    }

event_allocated:
    rc = clEventFree(gPubsEventInfo.eventHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventFree() failed [%#X]\n",rc);
    }

failure:
    return rc;
}

static ClCpmHandleT gClEvtPubsCpmHandle; /* FIXME */
ClRcT clEventPubsTerminate(ClInvocationT invocation,
			const SaNameT  *compName)
{
    ClRcT rc;

    rc = clCpmComponentUnregister(gClEvtPubsCpmHandle, compName, NULL);
    rc = clCpmClientFinalize(gClEvtPubsCpmHandle);

    clCpmResponse(gClEvtPubsCpmHandle, invocation, CL_OK);

    return CL_OK;
}
ClRcT
clCompAppTerminate(
    ClInvocationT       invocation,
    const SaNameT       *compName)
{
    ClRcT rc = CL_OK;

    clprintf ("Component [%s] : PID [%d]. Terminating\n",
              compName->value, mypid);

    /*
     * ---BEGIN_APPLICATION_CODE--- 
     */

    // ...

    /*
     * ---END_APPLICATION_CODE---
     */
    
    /*
     * Unregister with AMF and send back a response
     */

    if ( (rc = clCpmComponentUnregister(cpmHandle, compName, NULL)) )
        goto errorexit;
    if ( (rc = clCpmClientFinalize(cpmHandle)) )
        goto errorexit;

    clCpmResponse(cpmHandle, invocation, CL_OK);

    clprintf ("Component [%s] : PID [%d]. Terminated\n", compName->value, mypid);

    return rc;

errorexit:

    clprintf ("Component [%s] : PID [%d]. Termination error [0x%x]\n",
              compName->value, mypid, rc);

    return rc;
}
ClRcT
clCompAppTerminate(
    ClInvocationT       invocation,
    const ClNameT       *compName)
{
    ClRcT rc = CL_OK;

    clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%ld]. Terminating",
              compName->value, mypid);

    /*
     * ---BEGIN_APPLICATION_CODE--- 
     */

    // ...

    /*
     * ---END_APPLICATION_CODE---
     */
    
    /*
     * Unregister with AMF and send back a response
     */

    if ( (rc = clCpmComponentUnregister(cpmHandle, compName, NULL)) )
        goto errorexit;
    if ( (rc = clCpmClientFinalize(cpmHandle)) )
        goto errorexit;

    clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%ld]. Terminated", compName->value, mypid);
    clCpmResponse(cpmHandle, invocation, CL_OK);
    clEvalAppLogStreamClose(gEvalLogStream);

    return rc;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%s] : PID [%ld]. Termination error [0x%x]",
              compName->value, mypid, rc);

    return rc;
}