ClRcT
clAmsSAInitialize(
        CL_OUT      ClAmsClientHandleT                      *amsHandle,
        CL_IN       const ClAmsSAClientCallbacksT           *amsClientCallbacks,
        CL_INOUT    ClVersionT                              *version )
{

    ClRcT                                       rc = CL_OK; 
    clAmsClientInitializeRequestT               req;
    clAmsClientInitializeResponseT              *res = NULL;
    struct ams_instance                         *ams_instance = NULL;


    if (amsHandle == NULL || version == NULL)
    {
        return CL_AMS_RC(CL_ERR_NULL_POINTER);
    }
   
    /* 
     * Initialize the library and database 
     */

    if ((rc = check_lib_init())
            != CL_OK)
        goto error;

    /* 
     * Verify the version information 
     */

    if (( rc = clVersionVerify (
                    &version_database,
                    version))
            != CL_OK)
        goto error;

    /* 
     * Create the handle  
     */

    if ((rc = clHandleCreate (
                    handle_database,
                    sizeof(struct ams_instance),
                    amsHandle))
            != CL_OK)
        goto error;

    /* 
     * Check-Out the handle 
     */

    if ((rc = clHandleCheckout(
                    handle_database,
                    *amsHandle,
                    (void *)&ams_instance))
            != CL_OK)
        goto error;


    /* 
     * Initialize instance entry 
     */

    if (amsClientCallbacks) 
    {
        memcpy(&ams_instance->callbacks, amsClientCallbacks, sizeof(ClAmsSAClientCallbacksT));
    } 
    else 
    {
        memset(&ams_instance->callbacks, 0, sizeof(ClAmsSAClientCallbacksT));
    }

     if ( ( rc = clOsalMutexCreate(&ams_instance->response_mutex)) != CL_OK )
         goto error;

    /* 
     * Inform the server 
     */

    req.handle = *amsHandle;
    if ( (rc = cl_ams_client_initialize(
                    &req,
                    &res))
            != CL_OK)
        goto error;

    /* 
     * Decrement handle use count and return 
     */

    if ((rc = clHandleCheckin(
                    handle_database,
                    *amsHandle))
            != CL_OK)
        goto error;
   
    clHeapFree((void*)res);
    res = NULL;
    return CL_OK;

error:

    clHeapFree((void*)res);
    res = NULL;
    return CL_AMS_RC(rc);
}
/*-----------------------------------------------------------------------------
 * Initialize API
 *---------------------------------------------------------------------------*/
ClRcT clGmsInitialize(
    CL_OUT   ClGmsHandleT* const    gmsHandle,
    CL_IN    const ClGmsCallbacksT* const gmsCallbacks,
    CL_INOUT ClVersionT*   const      version)
{
    struct gms_instance *gms_instance_ptr = NULL;
    ClRcT rc = CL_OK;
    ClGmsClientInitRequestT req = {{0}};
    ClGmsClientInitResponseT *res = NULL;

    /* Step 0: Check readiness of library */

    rc = check_lib_init();
    if (rc != CL_OK)
    {
        return CL_GMS_RC(CL_ERR_NOT_INITIALIZED);
    }
    
    /* Step 1: Checking inputs */
    CL_ASSERT(gmsHandle != NULL);
    CL_ASSERT(version != NULL);
#if 0    
    if ((gmsHandle == NULL) || (version == NULL))
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }
#endif    

    *gmsHandle = CL_HANDLE_INVALID_VALUE;

    /* Step 2: Verifying version match */
    
    rc = clVersionVerify (&version_database, version);
    if (rc != CL_OK)
    {
        return CL_GMS_RC(CL_ERR_VERSION_MISMATCH); 
    }

    /* Step 3: Obtain unique handle */
    rc = clHandleCreate(gmsHandleDb, sizeof(struct gms_instance), gmsHandle);
    CL_ASSERT(rc == CL_OK);
#if 0    
    if (rc != CL_OK)
    {
        rc = CL_GMS_RC(CL_ERR_NO_RESOURCE);
        goto error_no_destroy;
    }
#endif    
    clLogInfo("GMS","CLT","GMS client handle is [%llX]",*gmsHandle);
    
    rc = clHandleCheckout(gmsHandleDb, *gmsHandle, (void **)&gms_instance_ptr);
    CL_ASSERT(rc == CL_OK);
    CL_ASSERT(gms_instance_ptr != NULL);
#if 0    
    if(rc != CL_OK)
    {
        goto error_destroy;
    }
    if (gms_instance_ptr == NULL)
    {
        clHandleCheckin(gmsHandleDb, *gmsHandle);
        rc = CL_GMS_RC(CL_ERR_NULL_POINTER);
        goto error_destroy;
    }
#endif

    rc = clGmsMutexCreate(&gms_instance_ptr->response_mutex);
    CL_ASSERT(rc == CL_OK);
#if 0    
    if(rc != CL_OK)
    {
        clHandleCheckin(gmsHandleDb, *gmsHandle);
        goto error_destroy;
    }
#endif

    /* Step 4: Negotiate version with the server */
    req.clientVersion.releaseCode = version->releaseCode;
    req.clientVersion.majorVersion= version->majorVersion;
    req.clientVersion.minorVersion= version->minorVersion;

    rc = cl_gms_clientlib_initialize_rmd(&req, 0x0 ,&res );
    if(rc != CL_OK )
    {
        clLogError(GEN,NA,"cl_gms_clientlib_initialize_rmd failed with rc:0x%x ",rc);
        clGmsMutexDelete(gms_instance_ptr->response_mutex);
        gms_instance_ptr->response_mutex = 0;
        clHandleCheckin(gmsHandleDb, *gmsHandle);
        rc = CL_GMS_RC(rc);
        goto error_destroy;
    }
    
    /* Step 5: Initialize instance entry */
    if (gmsCallbacks) 
    {
        memcpy(&gms_instance_ptr->callbacks, gmsCallbacks, sizeof(ClGmsCallbacksT));
    } 
    else 
    {
        memset(&gms_instance_ptr->callbacks, 0, sizeof(ClGmsCallbacksT));
    }

    memset(&gms_instance_ptr->cluster_notification_buffer, 0, sizeof(ClGmsClusterNotificationBufferT));
    memset(&gms_instance_ptr->group_notification_buffer, 0, sizeof(ClGmsGroupNotificationBufferT));

    /* Step 6: Decrement handle use count and return */
    if ((clHandleCheckin(gmsHandleDb, *gmsHandle)) != CL_OK)
    {
        clLogError(GEN,DB, "\nclHandleCheckin failed");
    }
    clHeapFree(res);
    return CL_OK;

    error_destroy:
    clHandleDestroy(gmsHandleDb, *gmsHandle);
    *gmsHandle = CL_HANDLE_INVALID_VALUE;

    //error_no_destroy:
    return rc;
}