/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
#ifndef OSCL_EXCLUSIVE_PTR_H_INCLUDED
#include "oscl_exclusive_ptr.h"
#endif
#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif
#ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
#include "pvmf_basic_errorinfomessage.h"
#endif
#ifndef PVMF_ERRORINFOMESSAGE_EXTENSION_H_INCLUDED
#include "pvmf_errorinfomessage_extension.h"
#endif
#ifndef PVMF_CPMPLUGIN_INTERFACE_H_INCLUDED
#include "pvmf_cpmplugin_interface.h"
#endif
#ifndef PVMF_CPMPLUGIN_AUTHORIZATION_INTERFACE_H_INCLUDED
#include "pvmf_cpmplugin_authorization_interface.h"
#endif
#ifndef PVMF_CPMPLUGIN_AUTHENTICATION_INTERFACE_H_INCLUDED
#include "pvmf_cpmplugin_authentication_interface.h"
#endif
#ifndef PVMF_CPMPLUGIN_ACCESS_INTERFACE_FACTORY_H_INCLUDED
#include "pvmf_cpmplugin_access_interface_factory.h"
#endif
#ifndef CPM_H_INCLUDED
#include "cpm.h"
#endif
#ifndef CPM_INTERNAL_H_INCLUDED
#include "cpm_internal.h"
#endif
#ifndef CPM_PLUGIN_REGISTRY_H
#include "cpm_plugin_registry.h"
#endif
#ifndef OSCL_DLL_H_INCLUDED
#include "oscl_dll.h"
#endif
#ifndef OSCL_MIME_STRING_UTILS_H
#include "pv_mime_string_utils.h"
#endif

// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()

#include "oscl_registry_access_client.h"

static CPMPluginRegistry* PopulateCPMPluginRegistry()
{
    //Connect to global component registry.
    OsclRegistryAccessClient cli;
    if (cli.Connect() != OsclErrNone)
        return NULL;

    //Get all the current CPM plugin factory functions.
    Oscl_Vector<OsclRegistryAccessElement, OsclMemAllocator> factories;
    OSCL_HeapString<OsclMemAllocator> id("X-CPM-PLUGIN");//PVMF_MIME_CPM_PLUGIN
    cli.GetFactories(id, factories);

    //Create registry
    CPMPluginRegistry* pRegistry = CPMPluginRegistryFactory::CreateCPMPluginRegistry();
    if (pRegistry)
    {
        //Create implementations of all plugins.
        Oscl_Vector<CPMPluginContainer, OsclMemAllocator> plugincontainers;
        for (uint32 i = 0;i < factories.size();i++)
        {
            if (factories[i].iFactory)
            {
                //Create an instance of the plugin.
                PVMFCPMPluginInterface* plugin = ((PVMFCPMPluginFactory*)factories[i].iFactory)->CreateCPMPlugin();
                if (plugin)
                {
                    //Package the plugin with its user authentication data.
                    CPMPluginContainer container(*plugin, NULL);
                    //Add the plugin to the registry with its mime string.
                    pRegistry->addPluginToRegistry(factories[i].iMimeString, container);
                }
            }
        }
    }
    cli.Close();
    return pRegistry;
}

static void DePopulateCPMPluginRegistry(CPMPluginRegistry* aRegistry)
{
    //Connect to global component registry.
    OsclRegistryAccessClient cli;
    if (cli.Connect() != OsclErrNone)
        return ;

    if (aRegistry)
    {
        OSCL_HeapString<OsclMemAllocator> mimetype;
        //Delete each plugin
        while (aRegistry->GetNumPlugIns())
        {
            if (aRegistry->GetPluginMimeType(0, mimetype))
            {
                //lookup the instance of this plugin
                CPMPluginContainer* container = aRegistry->lookupPlugin(mimetype);
                if (container)
                {
                    //lookup the factory for this plugin & delete its instance.
                    OsclComponentFactory factory = cli.GetFactory(mimetype);
                    if (factory)
                    {
                        ((PVMFCPMPluginFactory*)factory)->DestroyCPMPlugin(&container->PlugIn());
                    }
                }
                //remove it from the registry
                aRegistry->removePluginFromRegistry(mimetype);
            }
        }
        //Destroy the plugin registry
        CPMPluginRegistryFactory::DestroyCPMPluginRegistry(aRegistry);
    }
}

OSCL_EXPORT_REF
PVMFCPM* PVMFCPMFactory::CreateContentPolicyManager(PVMFCPMStatusObserver& aObserver)
{
    PVMFCPM* cpm = NULL;
    int32 err;
    OSCL_TRY(err,
             /*
              * Create Content Policy Manager
              */
             cpm = OSCL_NEW(PVMFCPMImpl, (aObserver));
            );
    if (err != OsclErrNone)
    {
        OSCL_LEAVE(err);
    }
    return (cpm);
}

OSCL_EXPORT_REF void PVMFCPMFactory::DestroyContentPolicyManager(PVMFCPM* aCPM)
{
    OSCL_DELETE(aCPM);
}

OSCL_EXPORT_REF PVMFCPMImpl::PVMFCPMImpl(PVMFCPMStatusObserver& aObserver,
        int32 aPriority)
        : OsclActiveObject(aPriority, "PVMFCPMImpl")
        , iObserver(aObserver)
{
    iPluginRegistry = NULL;
    iLogger = NULL;
    iNumQueryAuthenticationInterfacePending = 0;
    iNumQueryAuthenticationInterfaceComplete = 0;
    iNumRegisteredPlugInInitPending = 0;
    iNumRegisteredPlugInInitComplete = 0;
    iNumRegisteredPlugInResetPending = 0;
    iNumRegisteredPlugInResetComplete = 0;
    iNumQueryMetaDataExtensionInterfacePending = 0;
    iNumQueryMetaDataExtensionInterfaceComplete = 0;
    iLicenseInterface = NULL;
    iNumQueryCapConfigExtensionInterfacePending = 0;
    iNumQueryCapConfigExtensionInterfaceComplete = 0;

    iGetMetaDataKeysFromPlugInsDone = false;
    iGetMetaDataKeysInProgress = false;

    iExtensionRefCount = 0;
    iGetLicenseCmdId = 0;

    int32 err;
    OSCL_TRY(err,
             /*
              * Create the input command queue.  Use a reserve to avoid lots of
              * dynamic memory allocation
              */
             iInputCommands.Construct(PVMF_CPM_COMMAND_ID_START,
                                      PVMF_CPM_INTERNAL_CMDQ_SIZE);

             /*
              * Create the "current command" queue.  It will only contain one
              * command at a time, so use a reserve of 1
              */
             iCurrentCommand.Construct(0, 1);
             /*
              * Create the "cancel command" queue.  It will only contain one
              * command at a time, so use a reserve of 1.
              */
             iCancelCommand.Construct(0, 1);

            );
    if (err != OsclErrNone)
    {
        OSCL_LEAVE(err);
    }
}

PVMFCPMImpl::~PVMFCPMImpl()
{
    /*
     * Cleanup commands
     * The command queues are self-deleting, but we want to
     * notify the observer of unprocessed commands.
     */
    while (!iCancelCommand.empty())
    {
        CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure);
    }
    while (!iCurrentCommand.empty())
    {
        CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
    }
    while (!iInputCommands.empty())
    {
        CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
    }

    //Disconnect from all plugins in case it wasn't done in Reset.
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
    {
        if (it->iConnected)
            it->iPlugInInterface->Disconnect(it->iPlugInSessionID);
        it->iConnected = false;
    }

    /* Clear all vectors */
    iPlugInParamsVec.clear();
    iActivePlugInParamsVec.clear();
    iContentUsageContextVec.clear();
    iListofActiveSessions.clear();
}

OSCL_EXPORT_REF void PVMFCPMImpl::ThreadLogon()
{
    iLogger = PVLogger::GetLoggerObject("PVMFCPMImpl");

    AddToScheduler();
}

OSCL_EXPORT_REF void PVMFCPMImpl::ThreadLogoff()
{
    if (iPluginRegistry)
    {
        DePopulateCPMPluginRegistry(iPluginRegistry);
        iPluginRegistry = NULL;
        //clear the plugin params vec since all plugins are destroyed.
        iPlugInParamsVec.clear();
    }

    Cancel();

    if (IsAdded())
    {
        RemoveFromScheduler();
    }
}

OSCL_EXPORT_REF void PVMFCPMImpl::addRef()
{
    iExtensionRefCount++;
}

OSCL_EXPORT_REF void PVMFCPMImpl::removeRef()
{
    --iExtensionRefCount;
}

OSCL_EXPORT_REF bool PVMFCPMImpl::queryInterface(const PVUuid& uuid,
        PVInterface*& iface)
{
    iface = NULL;
    if (uuid == KPVMFMetadataExtensionUuid)
    {
        PVMFMetadataExtensionInterface* myInterface =
            OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        return true;
    }
    else if (uuid == PVMFCPMPluginLicenseInterfaceUuid)
    {
        PVMFCPMPluginLicenseInterface* myInterface =
            OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        return true;
    }
    else if (uuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
    {
        PvmiCapabilityAndConfig* myInterface =
            OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
        iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
        return true;
    }
    return false;
}

OSCL_EXPORT_REF PVMFCommandId PVMFCPMImpl::Init(const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:Init"));
    PVMFCPMCommand cmd;
    cmd.Construct(PVMF_CPM_INIT, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::OpenSession(PVMFSessionId& aSessionId,
                         const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:OpenSession"));
    PVMFCPMCommand cmd;
    cmd.Construct(PVMF_CPM_OPEN_SESSION,
                  &aSessionId,
                  aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::RegisterContent(PVMFSessionId aSessionId,
                             OSCL_wString& aSourceURL,
                             PVMFFormatType& aSourceFormat,
                             OsclAny* aSourceData,
                             const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:RegisterContent"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_REGISTER_CONTENT,
                  &aSourceURL,
                  &aSourceFormat,
                  aSourceData,
                  NULL,
                  aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFStatus
PVMFCPMImpl::GetContentAccessFactory(PVMFSessionId aSessionId,
                                     PVMFCPMPluginAccessInterfaceFactory*& aContentAccessFactory)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetContentAccessFactory"));

    aContentAccessFactory = NULL;
    CPMSessionInfo* sInfo = LookUpSessionInfo(aSessionId);
    if (sInfo != NULL)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                it->iPlugInAccessInterfaceFactory->addRef();
                aContentAccessFactory = it->iPlugInAccessInterfaceFactory;
                return PVMFSuccess;
            }
        }
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::GetContentAccessFactory - No Access Plugin"));
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::GetContentAccessFactory - Invalid Session ID"));
    }
    return PVMFFailure;
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::ApproveUsage(PVMFSessionId aSessionId,
                          PvmiKvp& aRequestedUsage,
                          PvmiKvp& aApprovedUsage,
                          PvmiKvp& aAuthorizationData,
                          PVMFCPMUsageID& aUsageID,
                          const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::ApproveUsage"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_APPROVE_USAGE,
                  &aRequestedUsage,
                  &aApprovedUsage,
                  &aAuthorizationData,
                  &aUsageID,
                  aContext);
    return QueueCommandL(cmd);
}

PVMFCPMContentType PVMFCPMImpl::GetCPMContentType(PVMFSessionId aSessionId)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetCPMContentType"));
    CPMSessionInfo* sInfo = LookUpSessionInfo(aSessionId);
    if (sInfo != NULL)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                return (it->iPlugInInterface->GetCPMContentType());
            }
        }
    }
    return PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
}

OSCL_EXPORT_REF PVMFStatus PVMFCPMImpl::GetCPMContentFilename(PVMFSessionId aSessionId, OSCL_wString& aFileName)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetCPMContentFilename"));
    CPMSessionInfo* sInfo = LookUpSessionInfo(aSessionId);
    if (sInfo != NULL)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                return (it->iPlugInInterface->GetCPMContentFilename(aFileName));
            }
        }
    }
    return PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
}


OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::UsageComplete(PVMFSessionId aSessionId,
                           PVMFCPMUsageID& aUsageID,
                           OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::UsageComplete"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_USAGE_COMPLETE,
                  NULL,
                  NULL,
                  &aUsageID,
                  NULL,
                  aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::CloseSession(PVMFSessionId& aSessionId,
                          const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::CloseSession"));
    PVMFCPMCommand cmd;
    cmd.Construct(PVMF_CPM_CLOSE_SESSION,
                  &aSessionId,
                  aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId PVMFCPMImpl::Reset(const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::Reset"));
    PVMFCPMCommand cmd;
    cmd.Construct(PVMF_CPM_RESET, aContext);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::GetNodeMetadataKeys(PVMFSessionId aSessionId,
                                 PVMFMetadataList& aKeyList,
                                 uint32 aStartingKeyIndex,
                                 int32 aMaxKeyEntries,
                                 char* aQueryKeyString,
                                 const OsclAny* aContextData)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetNodeMetadataKeys"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_GET_METADATA_KEYS,
                  aKeyList,
                  aStartingKeyIndex,
                  aMaxKeyEntries,
                  aQueryKeyString,
                  aContextData);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::GetNodeMetadataValues(PVMFSessionId aSessionId,
                                   PVMFMetadataList& aKeyList,
                                   Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
                                   uint32 aStartingValueIndex,
                                   int32 aMaxValueEntries,
                                   const OsclAny* aContextData)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetNodeMetadataValues"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_GET_METADATA_VALUES,
                  aKeyList,
                  aValueList,
                  aStartingValueIndex,
                  aMaxValueEntries,
                  aContextData);
    return QueueCommandL(cmd);
}

OSCL_EXPORT_REF PVMFStatus
PVMFCPMImpl::ReleaseNodeMetadataKeys(PVMFMetadataList& aKeyList,
                                     uint32 aStartingKeyIndex,
                                     uint32 aEndKeyIndex)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::ReleaseNodeMetadataKeys called"));
    if (((int32)aStartingKeyIndex < 0) ||
            (aStartingKeyIndex > aEndKeyIndex) ||
            (aKeyList.size() == 0))
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::ReleaseNodeMetadataKeys() Invalid start/end index"));
        return PVMFErrArgument;
    }
    if (aEndKeyIndex >= aKeyList.size())
    {
        aEndKeyIndex = aKeyList.size() - 1;
    }

    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        uint32 plugInStartIndex = it->iMetaDataKeyStartIndex;
        uint32 plugInEndIndex = it->iMetaDataKeyEndIndex;

        uint32 releaseStartIndex = 0;
        uint32 releaseEndIndex = 0;

        if ((aStartingKeyIndex >= plugInStartIndex) &&
                (aStartingKeyIndex <= plugInEndIndex))
        {
            releaseStartIndex = aStartingKeyIndex;
            if (aEndKeyIndex > plugInEndIndex)
            {
                releaseEndIndex = plugInEndIndex;
            }
            else
            {
                releaseEndIndex = aEndKeyIndex;
            }

            if (NULL != it->iPlugInMetaDataExtensionInterface)
            {
                it->iPlugInMetaDataExtensionInterface->ReleaseNodeMetadataKeys(aKeyList,
                        releaseStartIndex,
                        releaseEndIndex);
            }
        }
        aStartingKeyIndex = releaseEndIndex + 1;
    }
    return PVMFSuccess;
}

OSCL_EXPORT_REF PVMFStatus
PVMFCPMImpl::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList,
                                       uint32 aStartingValueIndex,
                                       uint32 aEndValueIndex)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::ReleaseNodeMetadataValues called"));

    if (((int32)aStartingValueIndex < 0) ||
            (aStartingValueIndex > aEndValueIndex) ||
            (aValueList.size() == 0))
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::ReleaseNodeMetadataValues() Invalid start/end index"));
        return PVMFErrArgument;
    }

    if (aEndValueIndex >= aValueList.size())
    {
        aEndValueIndex = aValueList.size() - 1;
    }

    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        uint32 plugInStartIndex = it->iMetaDataValueStartIndex;
        uint32 plugInEndIndex = it->iMetaDataValueEndIndex;

        uint32 releaseStartIndex = 0;
        uint32 releaseEndIndex = 0;

        if ((aStartingValueIndex >= plugInStartIndex) &&
                (aStartingValueIndex <= plugInEndIndex))
        {
            releaseStartIndex = aStartingValueIndex;
            if (aEndValueIndex > plugInEndIndex)
            {
                releaseEndIndex = plugInEndIndex;
            }
            else
            {
                releaseEndIndex = aEndValueIndex;
            }
            if (NULL != it->iPlugInMetaDataExtensionInterface)
            {
                it->iPlugInMetaDataExtensionInterface->ReleaseNodeMetadataValues(aValueList,
                        releaseStartIndex,
                        releaseEndIndex);
            }
        }
        aStartingValueIndex = releaseEndIndex + 1;
    }
    return PVMFSuccess;
}

OSCL_EXPORT_REF PVMFCommandId
PVMFCPMImpl::QueryInterface(PVMFSessionId aSessionId,
                            const PVUuid& aUuid,
                            PVInterface*& aInterfacePtr,
                            const OsclAny* aContext)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::GetNodeMetadataValues"));
    PVMFCPMCommand cmd;
    cmd.PVMFCPMCommandBase::Construct(aSessionId,
                                      PVMF_CPM_QUERY_INTERFACE,
                                      aUuid,
                                      aInterfacePtr,
                                      aContext);
    return QueueCommandL(cmd);
}


/**
 * This routine is called by various command APIs to queue an
 * asynchronous command for processing by the command handler AO.
 * This function may leave if the command can't be queued due to
 * memory allocation failure.
 */
PVMFCommandId PVMFCPMImpl::QueueCommandL(PVMFCPMCommand& aCmd)
{
    PVMFCommandId id;
    id = iInputCommands.AddL(aCmd);
    /* wakeup the AO */
    RunIfNotReady();
    return id;
}

/**
 * The various command handlers call this when a command is complete.
 */
void PVMFCPMImpl::CommandComplete(PVMFCPMCommandCmdQ& aCmdQ,
                                  PVMFCPMCommand& aCmd,
                                  PVMFStatus aStatus,
                                  OsclAny* aEventData,
                                  PVUuid* aEventUUID,
                                  int32* aEventCode)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
                      , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));

    PVInterface* extif = NULL;
    PVMFBasicErrorInfoMessage* errormsg = NULL;
    if (aEventUUID && aEventCode)
    {
        errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
        extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
    }

    /* create response */
    PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);

    /* Erase the command from the queue */
    aCmdQ.Erase(&aCmd);

    /* Report completion to the session observer */
    iObserver.CPMCommandCompleted(resp);

    if (errormsg)
    {
        errormsg->removeRef();
    }

    /* Reschedule AO if input command queue is not empty */
    if (!iInputCommands.empty()
            && IsAdded())
    {
        RunIfNotReady();
    }
}

void PVMFCPMImpl::CommandComplete(PVMFCPMCommandCmdQ& aCmdQ,
                                  PVMFCPMCommand& aCmd,
                                  PVMFStatus aStatus,
                                  PVInterface* aErrorExtIntf)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::CommandComplete Id %d Cmd %d Status %d"
                      , aCmd.iId, aCmd.iCmd, aStatus));

    /* create response */
    PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aErrorExtIntf, NULL);

    /* Erase the command from the queue */
    aCmdQ.Erase(&aCmd);

    /* Report completion to the session observer */
    iObserver.CPMCommandCompleted(resp);

    /* Reschedule AO if input command queue is not empty */
    if (!iInputCommands.empty())
    {
        RunIfNotReady();
    }
}

void
PVMFCPMImpl::MoveCmdToCurrentQueue(PVMFCPMCommand& aCmd)
{
    int32 err;
    OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
    if (err != OsclErrNone)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::MoveCmdToCurrentQueue - No Memory"));
        CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
        return;
    }
    iInputCommands.Erase(&aCmd);
    return;
}

void
PVMFCPMImpl::MoveCmdToCancelQueue(PVMFCPMCommand& aCmd)
{
    /*
     * note: the StoreL cannot fail since the queue is never more than 1 deep
     * and we reserved space.
     */
    iCancelCommand.StoreL(aCmd);
    iInputCommands.Erase(&aCmd);
}

PVMFCPMCommandContext* PVMFCPMImpl::RequestNewInternalCmd()
{
    int32 i = 0;
    /* Search for the next free node command in the pool */
    while (i < PVMF_CPM_INTERNAL_CMDQ_SIZE)
    {
        if (iInternalCmdPool[i].oFree)
        {
            iInternalCmdPool[i].oFree = false;
            return &(iInternalCmdPool[i]);
        }
        ++i;
    }
    /* Free one not found so return NULL */
    return NULL;
}

/**
 * Called by the command handler AO to process a command from
 * the input queue.
 * Return true if a command was processed, false if the command
 * processor is busy and can't process another command now.
 */
bool PVMFCPMImpl::ProcessCommand(PVMFCPMCommand& aCmd)
{
    /*
     * normally this node will not start processing one command
     * until the prior one is finished.  However, a hi priority
     * command such as Cancel must be able to interrupt a command
     * in progress.
     */
    if (!iCurrentCommand.empty() && !aCmd.hipri() && aCmd.iCmd != PVMF_CPM_CANCEL_GET_LICENSE)
        return false;

    switch (aCmd.iCmd)
    {
        case PVMF_CPM_INIT:
            DoInit(aCmd);
            break;

        case PVMF_CPM_OPEN_SESSION:
            DoOpenSession(aCmd);
            break;

        case PVMF_CPM_REGISTER_CONTENT:
            DoRegisterContent(aCmd);
            break;

        case PVMF_CPM_APPROVE_USAGE:
            DoApproveUsage(aCmd);
            break;

        case PVMF_CPM_USAGE_COMPLETE:
            DoUsageComplete(aCmd);
            break;

        case PVMF_CPM_CLOSE_SESSION:
            DoCloseSession(aCmd);
            break;

        case PVMF_CPM_RESET:
            DoReset(aCmd);
            break;

        case PVMF_CPM_GET_METADATA_KEYS:
        {
            PVMFStatus status = DoGetMetadataKeys(aCmd);
            if (status != PVMFPending)
            {
                CommandComplete(iInputCommands, aCmd, status);
            }
            else
            {
                MoveCmdToCurrentQueue(aCmd);
            }
        }
        break;

        case PVMF_CPM_GET_METADATA_VALUES:
            DoGetMetadataValues(aCmd);
            break;

        case PVMF_CPM_QUERY_INTERFACE:
            DoQueryInterface(aCmd);
            break;

        case PVMF_CPM_GET_LICENSE_W:
        {
            PVMFStatus status = DoGetLicense(aCmd, true);
            if (status == PVMFPending)
            {
                MoveCmdToCurrentQueue(aCmd);
            }
            else
            {
                CommandComplete(iInputCommands, aCmd, status);
            }
        }
        break;

        case PVMF_CPM_GET_LICENSE:
        {
            PVMFStatus status = DoGetLicense(aCmd);
            if (status == PVMFPending)
            {
                MoveCmdToCurrentQueue(aCmd);
            }
            else
            {
                CommandComplete(iInputCommands, aCmd, status);
            }
        }
        break;

        case PVMF_CPM_CANCEL_GET_LICENSE:
            DoCancelGetLicense(aCmd);
            break;

        default:
        {
            /* unknown command type */
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::ProcessCommand - Unknown Command"));
            CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
        }
        break;
    }

    return true;
}

void PVMFCPMImpl::DoInit(PVMFCPMCommand& aCmd)
{
    /*
     * Create plugin params for all registered plugins. This container class
     * holds all the required info about the plugin, thereby obviating the need
     * to query the registry all the time for info
     */
    iNumRegisteredPlugInInitPending = 0;
    iNumRegisteredPlugInInitComplete = 0;
    iNumQueryMetaDataExtensionInterfacePending = 0;
    iNumQueryMetaDataExtensionInterfaceComplete = 0;

    //create the plugin registry, instantiating all the current plugins
    //from the factory registry.
    //first remove any old registry.
    if (iPluginRegistry)
    {
        DePopulateCPMPluginRegistry(iPluginRegistry);
        /** Cleanup all registered plugins*/
        iPluginRegistry = NULL;
        /* Clear all vectors */
        iPlugInParamsVec.clear();
        iActivePlugInParamsVec.clear();
        iContentUsageContextVec.clear();
        iListofActiveSessions.clear();
        /**/
    }

    iPluginRegistry = PopulateCPMPluginRegistry();
    if (!iPluginRegistry)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoInit - PopulateCPMPluginRegistry Failed"));
        CommandComplete(iInputCommands, aCmd, PVMFFailure);
    }


    for (uint32 i = 0; i < iPluginRegistry->GetNumPlugIns(); i++)
    {
        CPMPlugInParams plugInParams;

        iPluginRegistry->GetPluginMimeType(i, plugInParams.iPlugInMimeType);
        plugInParams.iPlugInID = i;

        CPMPluginContainer* container =
            iPluginRegistry->lookupPlugin(plugInParams.iPlugInMimeType);

        if (container)
        {
            PVMFCPMPluginInterface& iface = container->PlugIn();
            OsclAny* _pPlugInData = container->PlugInUserAuthenticationData();
            plugInParams.iPlugInInterface = &iface;
            plugInParams.iPlugInData = _pPlugInData;
            iPlugInParamsVec.push_back(plugInParams);
        }
    }
    /* Connect with all plugins */
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
    {
        it->iPlugInSessionID = it->iPlugInInterface->Connect(*this);
        it->iConnected = true;
    }
    PVMFStatus status = InitRegisteredPlugIns();
    if (status == PVMFSuccess)
    {
        MoveCmdToCurrentQueue(aCmd);
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoInit - InitRegisteredPlugIns Failed"));
        CommandComplete(iInputCommands, aCmd, status);
    }
}

PVMFStatus PVMFCPMImpl::InitRegisteredPlugIns()
{
    if (iPlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            /* Get Authentication interface */
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd = PVMF_CPM_INTERNAL_INIT_CMD;
                internalCmd->parentCmd = PVMF_CPM_INIT;
                internalCmd->plugInID = it->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->Init(it->iPlugInSessionID,
                                           cmdContextData);
                iNumRegisteredPlugInInitPending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::InitRegisteredPlugIns - Registered plugin list empty"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteInitPlugIns()
{
    if (iNumRegisteredPlugInInitPending ==
            iNumRegisteredPlugInInitComplete)
    {
        PVMFStatus status = QueryForPlugInMetaDataExtensionInterface();

        if (status != PVMFSuccess)
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteInitPlugIns - QueryForPlugInAuthenticationInterface Failed"));
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            status);
        }
    }
}

PVMFStatus PVMFCPMImpl::QueryForPlugInMetaDataExtensionInterface()
{
    if (iPlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            /* Get MetaDataExtension interface */
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_METADATA_EXTENSION_INTERFACE_CMD;
                internalCmd->parentCmd = PVMF_CPM_INIT;
                internalCmd->plugInID = it->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     KPVMFMetadataExtensionUuid,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInMetaDataExtensionInterface),
                                                     cmdContextData);
                iNumQueryMetaDataExtensionInterfacePending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForPlugInMetaDataExtensionInterface - Registered plugin list empty"));
    return PVMFFailure;
}


void PVMFCPMImpl::CompleteMetaDataExtInterfaceQueryFromPlugIns()
{
    if (iNumQueryMetaDataExtensionInterfacePending ==
            iNumQueryMetaDataExtensionInterfaceComplete)
    {
        PVMFStatus status = QueryForPlugInCapConfigInterface();

        if (status != PVMFSuccess)
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteMetaDataExtInterfaceQueryFromPlugIns - QueryForPlugInCapConfigInterface Failed"));
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            status);
        }
    }
}

PVMFStatus PVMFCPMImpl::QueryForPlugInCapConfigInterface()
{
    if (iPlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            /* Get MetaDataExtension interface */
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_CAP_CONFIG_INTERFACE_CMD;
                internalCmd->parentCmd = PVMF_CPM_INIT;
                internalCmd->plugInID = it->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     PVMI_CAPABILITY_AND_CONFIG_PVUUID,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInCapConfigExtensionInterface),
                                                     cmdContextData);
                iNumQueryCapConfigExtensionInterfacePending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForPlugInCapConfigInterface - Registered plugin list empty"));
    return PVMFFailure;
}


void PVMFCPMImpl::CompleteCapConfigExtInterfaceQueryFromPlugIns()
{
    if (iNumQueryCapConfigExtensionInterfacePending ==
            iNumQueryCapConfigExtensionInterfaceComplete)
    {
        PVMFStatus status = QueryForPlugInAuthenticationInterface();

        if (status != PVMFSuccess)
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteCapConfigExtInterfaceQueryFromPlugIns - QueryForPlugInAuthenticationInterface Failed"));
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            status);
        }
    }
}

PVMFStatus PVMFCPMImpl::QueryForPlugInAuthenticationInterface()
{
    if (iPlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            /* Get Authentication interface */
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_AUTHENTICATION_INTERFACE_CMD;
                internalCmd->parentCmd = PVMF_CPM_INIT;
                internalCmd->plugInID = it->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     PVMFCPMPluginAuthenticationInterfaceUuid,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInAuthenticationInterface),
                                                     cmdContextData);
                iNumQueryAuthenticationInterfacePending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForPlugInAuthenticationInterface - Registered plugin list empty"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteCPMInit()
{
    if (iNumQueryAuthenticationInterfacePending ==
            iNumQueryAuthenticationInterfaceComplete)
    {
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFSuccess);
    }
}

void PVMFCPMImpl::DoOpenSession(PVMFCPMCommand& aCmd)
{
    PVMFSessionId* sessionIdPtr;
    aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, sessionIdPtr));

    /* Create a session info */
    CPMSessionInfo sessionInfo;
    sessionInfo.iSessionId = iListofActiveSessions.size();
    *sessionIdPtr = sessionInfo.iSessionId;
    iListofActiveSessions.push_back(sessionInfo);
    PVMFStatus status =
        AuthenticateWithAllRegisteredPlugIns(sessionInfo.iSessionId);
    if (status == PVMFSuccess)
    {
        MoveCmdToCurrentQueue(aCmd);
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoOpenSession - AuthenticateWithAllRegisteredPlugIns Failed"));
        CommandComplete(iInputCommands, aCmd, status);
    }
}

PVMFStatus PVMFCPMImpl::AuthenticateWithAllRegisteredPlugIns(PVMFSessionId aSessionId)
{
    if (iPlugInParamsVec.size() > 0)
    {
        CPMSessionInfo* sessionInfo = LookUpSessionInfo(aSessionId);

        if (sessionInfo != NULL)
        {
            Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
            for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
            {
                /* Get Authentication interface */
                PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
                if (internalCmd != NULL)
                {
                    internalCmd->cmd = PVMF_CPM_INTERNAL_AUTHENTICATE_CMD;
                    internalCmd->parentCmd = PVMF_CPM_OPEN_SESSION;
                    internalCmd->plugInID = it->iPlugInID;
                    OsclAny *cmdContextData =
                        OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                    it->iPlugInAuthenticationInterface->AuthenticateUser(it->iPlugInSessionID,
                            it->iPlugInData,
                            cmdContextData);
                    sessionInfo->iNumPlugInAunthenticateRequestsPending++;
                }
                else
                {
                    return PVMFErrNoMemory;
                }
            }
            return PVMFSuccess;
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::AuthenticateWithAllRegisteredPlugIns - Invalid Session ID"));
            return PVMFErrArgument;
        }
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::AuthenticateWithAllRegisteredPlugIns - Registered plugin list empty"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteOpenSession(CPMSessionInfo* aSessionInfo)
{
    if (aSessionInfo == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteOpenSession - Invalid Session ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aSessionInfo->iNumPlugInAunthenticateRequestsComplete++;

        if (aSessionInfo->iNumPlugInAunthenticateRequestsComplete ==
                aSessionInfo->iNumPlugInAunthenticateRequestsPending)
        {
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFSuccess);
        }
    }
    return;
}

void PVMFCPMImpl::DoRegisterContent(PVMFCPMCommand& aCmd)
{
    OSCL_wString* sourceURL;
    PVMFFormatType* sourceFormatType;
    OsclAny* aSourceData;
    OsclAny* placeHolder;

    aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, sourceURL),
               OSCL_STATIC_CAST(OsclAny*&, sourceFormatType),
               aSourceData,
               placeHolder);

    CPMSessionInfo* sInfo = LookUpSessionInfo(aCmd.iSession);

    if (sInfo != NULL)
    {
        sInfo->iSourceURL = *sourceURL;
        sInfo->iSourceFormatType = *sourceFormatType;
        sInfo->iSourceData = aSourceData;
        PVMFStatus status = PopulateListOfActivePlugIns(sInfo);
        if (status == PVMFSuccess)
        {
            status = QueryForAuthorizationInterface(sInfo);
            if (status == PVMFSuccess)
            {
                MoveCmdToCurrentQueue(aCmd);
            }
            else
            {
                PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoRegisterContent - QueryForAuthorizationInterface Failed"));
                CommandComplete(iInputCommands, aCmd, status);
            }
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoRegisterContent - PopulateListOfActivePlugIns Failed"));
            CommandComplete(iInputCommands, aCmd, status);
        }
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoRegisterContent - Invalid Session ID"));
        CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
    }
}

PVMFStatus PVMFCPMImpl::PopulateListOfActivePlugIns(CPMSessionInfo* aInfo)
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
    {
        PVMFStatus status =
            it->iPlugInInterface->SetSourceInitializationData(aInfo->iSourceURL,
                    aInfo->iSourceFormatType,
                    aInfo->iSourceData);
        if (status == PVMFSuccess)
        {
            /* Add this plug to the active list */
            iActivePlugInParamsVec.push_back(*it);
        }
    }
    if (iActivePlugInParamsVec.size() > 0)
    {
        return PVMFSuccess;
    }
    //no plugins care about this clip
    return PVMFErrNotSupported;
}

PVMFStatus PVMFCPMImpl::QueryForAuthorizationInterface(CPMSessionInfo* aInfo)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_AUTHORIZATION_INTERFACE_CMD;
                internalCmd->parentCmd = PVMF_CPM_REGISTER_CONTENT;
                internalCmd->plugInID = it->iPlugInID;
                internalCmd->sessionid = aInfo->iSessionId;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     PVMFCPMPluginAuthorizationInterfaceUuid,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInAuthorizationInterface),
                                                     cmdContextData);
                aInfo->iNumPlugInAuthorizeInterfaceQueryRequestsPending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForAuthorizationInterface - No Active Plugins"));
    return PVMFFailure;
}

PVMFStatus PVMFCPMImpl::QueryForAccessInterfaceFactory(CPMSessionInfo* aInfo)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_ACCESS_INTERFACE_FACTORY_CMD;
                internalCmd->parentCmd = PVMF_CPM_REGISTER_CONTENT;
                internalCmd->plugInID = it->iPlugInID;
                internalCmd->sessionid = aInfo->iSessionId;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     PVMFCPMPluginAccessInterfaceFactoryUuid,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInAccessInterfaceFactory),
                                                     cmdContextData);
                aInfo->iNumPlugInAccessInterfaceFactoryQueryRequestsPending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForAccessInterfaceFactory - No Active Plugins"));
    return PVMFFailure;
}

PVMFStatus PVMFCPMImpl::DetermineAccessPlugIn(CPMSessionInfo* aInfo)
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInAccessInterfaceFactory != NULL)
        {
            aInfo->iAccessPlugInID = it->iPlugInID;
            return PVMFSuccess;
        }
    }
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DetermineAccessPlugIn Failed"));
    return PVMFFailure;
}

PVMFStatus PVMFCPMImpl::QueryForLicenseInterface(CPMSessionInfo* aInfo)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd =
                    PVMF_CPM_INTERNAL_QUERY_LICENSE_INTERFACE_CMD;
                internalCmd->parentCmd = PVMF_CPM_REGISTER_CONTENT;
                internalCmd->plugInID = it->iPlugInID;
                internalCmd->sessionid = aInfo->iSessionId;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->QueryInterface(it->iPlugInSessionID,
                                                     PVMFCPMPluginLicenseInterfaceUuid,
                                                     OSCL_STATIC_CAST(PVInterface*&, it->iPlugInLicenseInterface),
                                                     cmdContextData);
                aInfo->iNumPlugInLicenseAcquisitionInterfaceRequestsPending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForLicenseInterface - No Active Plugins"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteRegisterContentPhase1(CPMSessionInfo* aInfo)
{
    if (aInfo == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteRegisterContentPhase1 - Invalid Session ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aInfo->iNumPlugInAuthorizeInterfaceQueryRequestsComplete++;

        if (aInfo->iNumPlugInAuthorizeInterfaceQueryRequestsComplete ==
                aInfo->iNumPlugInAuthorizeInterfaceQueryRequestsPending)
        {
            PVMFStatus status = QueryForAccessInterfaceFactory(aInfo);
            if (status != PVMFSuccess)
            {
                PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteRegisterContentPhase1 - QueryForAccessInterfaceFactory Failed"));
                CommandComplete(iCurrentCommand,
                                iCurrentCommand.front(),
                                status);
            }
        }
    }
    return;
}

void PVMFCPMImpl::CompleteRegisterContentPhase2(CPMSessionInfo* aInfo)
{
    if (aInfo == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteRegisterContentPhase2 - Invalid Session ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aInfo->iNumPlugInAccessInterfaceFactoryQueryRequestsComplete++;

        if (aInfo->iNumPlugInAccessInterfaceFactoryQueryRequestsComplete ==
                aInfo->iNumPlugInAccessInterfaceFactoryQueryRequestsPending)
        {
            PVMFStatus status = DetermineAccessPlugIn(aInfo);
            if (status != PVMFSuccess)
            {
                CommandComplete(iCurrentCommand,
                                iCurrentCommand.front(),
                                status);
            }
            else
            {
                status = QueryForLicenseInterface(aInfo);
                if (status != PVMFSuccess)
                {
                    CommandComplete(iCurrentCommand,
                                    iCurrentCommand.front(),
                                    status);
                }
            }
        }
    }
    return;
}

void PVMFCPMImpl::CompleteRegisterContentPhase3(CPMSessionInfo* aInfo)
{
    if (aInfo == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteRegisterContentPhase3 - Invalid Session ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aInfo->iNumPlugInLicenseAcquisitionInterfaceRequestsComplete++;

        if (aInfo->iNumPlugInLicenseAcquisitionInterfaceRequestsComplete ==
                aInfo->iNumPlugInLicenseAcquisitionInterfaceRequestsPending)
        {
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFSuccess);
        }
    }
    return;
}


void PVMFCPMImpl::DoApproveUsage(PVMFCPMCommand& aCmd)
{
    PvmiKvp* requestedUsage;
    PvmiKvp* approvedUsage;
    PvmiKvp* authorizationData;
    PVMFCPMUsageID* usageID;

    aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, requestedUsage),
               OSCL_STATIC_CAST(OsclAny*&, approvedUsage),
               OSCL_STATIC_CAST(OsclAny*&, authorizationData),
               OSCL_STATIC_CAST(OsclAny*&, usageID));

    /* Create Usage context */
    *usageID = iContentUsageContextVec.size();
    CPMContentUsageContext usageContext;
    usageContext.iUsageID = *usageID;
    iContentUsageContextVec.push_back(usageContext);

    PVMFStatus status = RequestApprovalFromActivePlugIns(aCmd);
    if (status == PVMFSuccess)
    {
        MoveCmdToCurrentQueue(aCmd);
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoApproveUsage - RequestApprovalFromActivePlugIns Failed"));
        CommandComplete(iInputCommands, aCmd, status);
    }
}

PVMFStatus PVMFCPMImpl::RequestApprovalFromActivePlugIns(PVMFCPMCommand& aCmd)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        PvmiKvp* requestedUsage;
        PvmiKvp* approvedUsage;
        PvmiKvp* authorizationData;
        PVMFCPMUsageID* usageID;

        aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, requestedUsage),
                   OSCL_STATIC_CAST(OsclAny*&, approvedUsage),
                   OSCL_STATIC_CAST(OsclAny*&, authorizationData),
                   OSCL_STATIC_CAST(OsclAny*&, usageID));

        CPMSessionInfo* sInfo = LookUpSessionInfo(aCmd.iSession);
        CPMContentUsageContext* usageContext = LookUpContentUsageContext(*usageID);
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
                if (internalCmd != NULL)
                {
                    internalCmd->cmd = PVMF_CPM_INTERNAL_AUTHORIZE_CMD;
                    internalCmd->parentCmd = PVMF_CPM_APPROVE_USAGE;
                    internalCmd->plugInID = it->iPlugInID;
                    internalCmd->usageid = *usageID;
                    OsclAny *cmdContextData =
                        OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                    it->iPlugInAuthorizationInterface->AuthorizeUsage(it->iPlugInSessionID,
                            *requestedUsage,
                            *approvedUsage,
                            *authorizationData,
                            it->iAuthorizationRequestTimeOut,
                            cmdContextData);
                    OSCL_ASSERT(usageContext);
                    if (!usageContext)
                    {
                        return PVMFFailure;
                    }
                    usageContext->iNumAuthorizeRequestsPending++;
                }
                else
                {
                    return PVMFErrNoMemory;
                }
            }
        }
        return PVMFSuccess;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::RequestApprovalFromActivePlugIns - No Active Plugins"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteApproveUsage(CPMContentUsageContext* aContext)
{
    if (aContext == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteApproveUsage - Invalid Usage ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aContext->iNumAuthorizeRequestsComplete++;

        if (aContext->iNumAuthorizeRequestsComplete ==
                aContext->iNumAuthorizeRequestsPending)
        {
            if (CheckForMetaDataInterfaceAvailability())
            {
                PVMFStatus status = QueryForMetaDataKeys(iCurrentCommand.front());
                if (status != PVMFSuccess)
                {
                    CommandComplete(iCurrentCommand,
                                    iCurrentCommand.front(),
                                    status);
                }
            }
            else
            {
                // No meta data
                CommandComplete(iCurrentCommand,
                                iCurrentCommand.front(),
                                PVMFSuccess);
            }
        }
    }
    return;
}

bool PVMFCPMImpl::CheckForMetaDataInterfaceAvailability()
{
    uint32 num = 0;
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInMetaDataExtensionInterface != NULL)
            {
                num++;
            }
        }
        if (num > 0)
        {
            return true;
        }
    }
    return false;
}

PVMFStatus PVMFCPMImpl::QueryForMetaDataKeys(PVMFCPMCommand& aParentCmd)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInMetaDataExtensionInterface != NULL)
            {
                PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
                if (internalCmd != NULL)
                {
                    internalCmd->cmd =
                        PVMF_CPM_INTERNAL_GET_PLUGIN_META_DATA_KEYS_CMD;
                    internalCmd->parentCmd = aParentCmd.iCmd;
                    internalCmd->plugInID = it->iPlugInID;
                    OsclAny *cmdContextData =
                        OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                    it->iNumMetaDataKeysAvailable  = 0;
                    it->iAvailableMetadataKeys.clear();

                    it->iNumMetaDataKeysAvailable =
                        it->iPlugInMetaDataExtensionInterface->GetNumMetadataKeys();
                    it->iPlugInMetaDataExtensionInterface->GetNodeMetadataKeys(it->iPlugInSessionID,
                            it->iAvailableMetadataKeys,
                            0,
                            it->iNumMetaDataKeysAvailable,
                            NULL,
                            cmdContextData);
                }
                else
                {
                    return PVMFErrNoMemory;
                }
            }
            else
            {
                it->iGetMetaDataKeysComplete = true;
            }
        }
        return PVMFSuccess;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::QueryForMetaDataKeys - No Active Plugins"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteGetMetaDataKeys(uint32 aPlugInID)
{
    CPMPlugInParams* pluginInParams = LookUpPlugInParamsFromActiveList(aPlugInID);
    if (pluginInParams == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteGetMetaDataKeys - Invalid PlugIn ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        pluginInParams->iGetMetaDataKeysComplete = true;
        if (CheckForGetMetaDataKeysCompletion())
        {
            PVMFStatus status = PVMFSuccess;
            if (iGetMetaDataKeysInProgress == true)
            {
                status = CompleteDoGetMetadataKeys(iCurrentCommand.front());
            }
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            status);
            iGetMetaDataKeysFromPlugInsDone = true;
        }
    }
    return;
}

bool PVMFCPMImpl::CheckForGetMetaDataKeysCompletion()
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInMetaDataExtensionInterface != NULL)
        {
            if (it->iGetMetaDataKeysComplete == false)
            {
                return false;
            }
        }
    }
    return true;
}


void PVMFCPMImpl::DoUsageComplete(PVMFCPMCommand& aCmd)
{
    OsclAny* placeHolder1;
    OsclAny* placeHolder2;
    OsclAny* placeHolder3;
    PVMFCPMUsageID* usageID;

    aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, placeHolder1),
               OSCL_STATIC_CAST(OsclAny*&, placeHolder2),
               OSCL_STATIC_CAST(OsclAny*&, usageID),
               OSCL_STATIC_CAST(OsclAny*&, placeHolder3));

    PVMFStatus status = SendUsageCompleteToRegisteredPlugIns(*usageID);
    if (status == PVMFSuccess)
    {
        MoveCmdToCurrentQueue(aCmd);
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoUsageComplete - SendUsageCompleteToRegisteredPlugIns Failed"));
        CommandComplete(iInputCommands, aCmd, status);
    }
}

PVMFStatus PVMFCPMImpl::SendUsageCompleteToRegisteredPlugIns(PVMFCPMUsageID aID)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        CPMContentUsageContext* usageContext = LookUpContentUsageContext(aID);
        if (usageContext != NULL)
        {
            Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
            for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
            {
                PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
                if (internalCmd != NULL)
                {
                    internalCmd->cmd = PVMF_CPM_INTERNAL_USAGE_COMPLETE_CMD;
                    internalCmd->parentCmd = PVMF_CPM_USAGE_COMPLETE;
                    internalCmd->plugInID = it->iPlugInID;
                    internalCmd->usageid = aID;
                    OsclAny *cmdContextData =
                        OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                    it->iPlugInAuthorizationInterface->UsageComplete(it->iPlugInSessionID,
                            cmdContextData);
                    usageContext->iNumUsageCompleteRequestsPending++;
                }
                else
                {
                    return PVMFErrNoMemory;
                }
            }
            return PVMFSuccess;
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::SendUsageCompleteToRegisteredPlugIns - Invalid UsageContext"));
            return PVMFFailure;
        }
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::SendUsageCompleteToRegisteredPlugIns - No Active Plugins"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteUsageComplete(CPMContentUsageContext* aContext)
{
    if (aContext == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteUsageComplete - Invalid Usage ID"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFFailure);
    }
    else
    {
        aContext->iNumUsageCompleteRequestsComplete++;

        if (aContext->iNumUsageCompleteRequestsComplete ==
                aContext->iNumUsageCompleteRequestsPending)
        {
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFSuccess);
        }
    }
    return;
}

void PVMFCPMImpl::DoCloseSession(PVMFCPMCommand& aCmd)
{
    PVMFSessionId* sessionId;
    aCmd.Parse(OSCL_STATIC_CAST(OsclAny*&, sessionId));

    CPMSessionInfo* sessionInfo = NULL;

    Oscl_Vector<CPMSessionInfo, OsclMemAllocator>::iterator it;
    for (it = iListofActiveSessions.begin(); it != iListofActiveSessions.end(); it++)
    {
        if (it->iSessionId == *sessionId)
        {
            sessionInfo = it;
            break;
        }
    }
    if (sessionInfo == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoCloseSession - Invalid Session ID"));
        CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
        return;
    }
    iListofActiveSessions.erase(it);
    CommandComplete(iInputCommands, aCmd, PVMFSuccess);
    return;
}

void PVMFCPMImpl::DoReset(PVMFCPMCommand& aCmd)
{
    PVMFStatus status = ResetRegisteredPlugIns();
    if (status == PVMFSuccess)
    {
        MoveCmdToCurrentQueue(aCmd);
    }
    else
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoReset - ResetRegisteredPlugIns Failed"));
        CommandComplete(iInputCommands, aCmd, status);
    }
    iNumRegisteredPlugInInitPending = 0;
    iNumRegisteredPlugInInitComplete = 0;
    iNumQueryMetaDataExtensionInterfacePending = 0;
    iNumQueryMetaDataExtensionInterfaceComplete = 0;

    iGetMetaDataKeysFromPlugInsDone = false;
    iGetMetaDataKeysInProgress = false;

}

PVMFStatus PVMFCPMImpl::ResetRegisteredPlugIns()
{
    if (iPlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            /* Get Authentication interface */
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd = PVMF_CPM_INTERNAL_RESET_CMD;
                internalCmd->parentCmd = PVMF_CPM_RESET;
                internalCmd->plugInID = it->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                it->iPlugInInterface->Reset(it->iPlugInSessionID,
                                            cmdContextData);
                iNumRegisteredPlugInResetPending++;
            }
            else
            {
                return PVMFErrNoMemory;
            }
        }
        return PVMFSuccess;
    }
    /* No registered plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::ResetRegisteredPlugIns - Registered plugin list empty"));
    return PVMFFailure;
}

void PVMFCPMImpl::CompleteCPMReset()
{
    if (iNumRegisteredPlugInResetPending ==
            iNumRegisteredPlugInResetComplete)
    {
        /* Disonnect from all plugins */
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
        {
            if (it->iConnected)
                it->iPlugInInterface->Disconnect(it->iPlugInSessionID);
            it->iConnected = false;
        }
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFSuccess);
    }
}

void PVMFCPMImpl::DoQueryInterface(PVMFCPMCommand& aCmd)
{
    PVUuid* uuid;
    PVInterface** ptr;
    aCmd.PVMFCPMCommandBase::Parse(uuid, ptr);

    PVMFStatus status = PVMFErrNotSupported;
    PVInterface* iFace = NULL;
    if (queryInterface(*uuid, iFace))
    {
        status = PVMFSuccess;
        *ptr = OSCL_STATIC_CAST(PVInterface*, iFace);
    }
    CommandComplete(iInputCommands, aCmd, status);
    return;
}

void PVMFCPMImpl::Run()
{
    /*
     * Process commands.
     */
    if (!iInputCommands.empty())
    {
        ProcessCommand(iInputCommands.front());
    }
}

void PVMFCPMImpl::CPMPluginCommandCompleted(const PVMFCmdResp& aResponse)
{
    PVMFCPMCommandContext *cmdContextData =
        OSCL_REINTERPRET_CAST(PVMFCPMCommandContext*, aResponse.GetContext());

    cmdContextData->oFree = true;

    if (cmdContextData->cmd == PVMF_CPM_INTERNAL_CANCEL_GET_LICENSE)
    {
        PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::CompleteCancelGetLicense - status=%d", aResponse.GetCmdStatus()));
        CommandComplete(iCancelCommand,
                        iCancelCommand.front(),
                        aResponse.GetCmdStatus());
        return;
    }
    if (aResponse.GetCmdStatus() != PVMFSuccess)
    {
        if (((cmdContextData->cmd == PVMF_CPM_INTERNAL_QUERY_METADATA_EXTENSION_INTERFACE_CMD) ||
                (cmdContextData->cmd == PVMF_CPM_INTERNAL_QUERY_CAP_CONFIG_INTERFACE_CMD) ||
                (cmdContextData->cmd == PVMF_CPM_INTERNAL_QUERY_LICENSE_INTERFACE_CMD)) &&
                (aResponse.GetCmdStatus() == PVMFErrNotSupported))
        {
            /*
             * Do nothing - Not all plugins have to support:
             * metadata, license interface
             */
        }
        else
        {
            /*
             * This call is in response to a command issued by CPM to one
             * of its plugins. This also means that there is current
             * command in the iCurrentCommand queue blocking the command loop
             * waiting for the all plugin commands to complete. Report failure
             * on it in case the parent id of this command is same as that of
             * the current blocking command. In case more than one child node
             * report error on same parent command, then the first one to
             * report would report failure on the parent command, and subsequent
             * ones would just log errors and return.
             */
            if (iCurrentCommand.size() > 0)
            {
                if (cmdContextData->parentCmd == iCurrentCommand.front().iCmd)
                {
                    /* pass up any extra error info, if any */
                    CommandComplete(iCurrentCommand,
                                    iCurrentCommand.front(),
                                    aResponse.GetCmdStatus(),
                                    aResponse.GetEventExtensionInterface());
                    return;
                }
            }
        }
    }

    switch (cmdContextData->cmd)
    {
        case PVMF_CPM_INTERNAL_INIT_CMD:
            iNumRegisteredPlugInInitComplete++;
            CompleteInitPlugIns();
            break;

        case PVMF_CPM_INTERNAL_QUERY_METADATA_EXTENSION_INTERFACE_CMD:
            iNumQueryMetaDataExtensionInterfaceComplete++;
            CompleteMetaDataExtInterfaceQueryFromPlugIns();
            break;

        case PVMF_CPM_INTERNAL_QUERY_AUTHENTICATION_INTERFACE_CMD:
            iNumQueryAuthenticationInterfaceComplete++;
            CompleteCPMInit();
            break;

        case PVMF_CPM_INTERNAL_AUTHENTICATE_CMD:
        {
            CPMSessionInfo* sessionInfo =
                LookUpSessionInfo(cmdContextData->sessionid);
            CompleteOpenSession(sessionInfo);
        }
        break;

        case PVMF_CPM_INTERNAL_QUERY_AUTHORIZATION_INTERFACE_CMD:
        {
            CPMSessionInfo* sessionInfo =
                LookUpSessionInfo(cmdContextData->sessionid);
            CompleteRegisterContentPhase1(sessionInfo);
        }
        break;

        case PVMF_CPM_INTERNAL_QUERY_ACCESS_INTERFACE_FACTORY_CMD:
        {
            CPMSessionInfo* sessionInfo =
                LookUpSessionInfo(cmdContextData->sessionid);
            CompleteRegisterContentPhase2(sessionInfo);
        }
        break;

        case PVMF_CPM_INTERNAL_QUERY_LICENSE_INTERFACE_CMD:
        {
            CPMSessionInfo* sessionInfo =
                LookUpSessionInfo(cmdContextData->sessionid);
            CompleteRegisterContentPhase3(sessionInfo);
        }
        break;

        case PVMF_CPM_INTERNAL_AUTHORIZE_CMD:
        {
            CPMContentUsageContext* usageContext =
                LookUpContentUsageContext(cmdContextData->usageid);
            CompleteApproveUsage(usageContext);
            CPMPlugInParams* plugInParams =
                LookUpPlugInParams(cmdContextData->plugInID);
            OSCL_ASSERT(plugInParams);
            if (plugInParams)
                plugInParams->iAuthorized = true;
        }
        break;

        case PVMF_CPM_INTERNAL_USAGE_COMPLETE_CMD:
        {
            CPMContentUsageContext* usageContext =
                LookUpContentUsageContext(cmdContextData->usageid);
            CompleteUsageComplete(usageContext);
            CPMPlugInParams* plugInParams =
                LookUpPlugInParams(cmdContextData->plugInID);
            OSCL_ASSERT(plugInParams);
            if (plugInParams)
                plugInParams->iAuthorized = false;
        }
        break;

        case PVMF_CPM_INTERNAL_RESET_CMD:
            iNumRegisteredPlugInResetComplete++;
            CompleteCPMReset();
            break;

        case PVMF_CPM_INTERNAL_GET_PLUGIN_META_DATA_KEYS_CMD:
            CompleteGetMetaDataKeys(cmdContextData->plugInID);
            break;

        case PVMF_CPM_INTERNAL_GET_PLUGIN_META_DATA_VALUES_CMD:
        {
            CompleteGetMetaDataValues(cmdContextData);
        }
        break;

        case PVMF_CPM_INTERNAL_GET_LICENSE_CMD:
        {
            CompleteGetLicense();
        }
        break;

        case PVMF_CPM_INTERNAL_QUERY_CAP_CONFIG_INTERFACE_CMD:
            iNumQueryCapConfigExtensionInterfaceComplete++;
            CompleteCapConfigExtInterfaceQueryFromPlugIns();
            break;

        default:
            break;
    }
    return;
}

CPMSessionInfo*
PVMFCPMImpl::LookUpSessionInfo(PVMFSessionId aID)
{
    Oscl_Vector<CPMSessionInfo, OsclMemAllocator>::iterator it;
    for (it = iListofActiveSessions.begin(); it != iListofActiveSessions.end(); it++)
    {
        if (it->iSessionId == aID)
        {
            return (it);
        }
    }
    return NULL;
}

CPMContentUsageContext* PVMFCPMImpl::LookUpContentUsageContext(PVMFCPMUsageID aID)
{
    Oscl_Vector<CPMContentUsageContext, OsclMemAllocator>::iterator it;
    for (it = iContentUsageContextVec.begin(); it != iContentUsageContextVec.end(); it++)
    {
        if (it->iUsageID == aID)
        {
            return (it);
        }
    }
    return NULL;
}

CPMPlugInParams* PVMFCPMImpl::LookUpPlugInParams(uint32 aID)
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iPlugInParamsVec.begin(); it != iPlugInParamsVec.end(); it++)
    {
        if (it->iPlugInID == aID)
        {
            return (it);
        }
    }
    return NULL;
}

CPMPlugInParams* PVMFCPMImpl::LookUpPlugInParamsFromActiveList(uint32 aID)
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInID == aID)
        {
            return (it);
        }
    }
    return NULL;
}

OSCL_EXPORT_REF uint32
PVMFCPMImpl::GetNumMetadataKeys(char* aQueryKeyString)
{
    uint32 numMetaDataKeys = 0;
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (NULL != it->iPlugInMetaDataExtensionInterface)
            {
                numMetaDataKeys +=
                    it->iPlugInMetaDataExtensionInterface->GetNumMetadataKeys(aQueryKeyString);
            }
        }
        return numMetaDataKeys;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::GetNumMetadataKeys - No Active Plugins"));
    return numMetaDataKeys;
}

OSCL_EXPORT_REF uint32
PVMFCPMImpl::GetNumMetadataValues(PVMFMetadataList& aKeyList)
{
    uint32 numMetaDataValues = 0;
    if (iActivePlugInParamsVec.size() > 0)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (NULL != it->iPlugInMetaDataExtensionInterface)
            {
                numMetaDataValues +=
                    it->iPlugInMetaDataExtensionInterface->GetNumMetadataValues(aKeyList);
            }
        }
        return numMetaDataValues;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::GetNumMetadataValues - No Active Plugins"));
    return numMetaDataValues;
}

PVMFStatus
PVMFCPMImpl::DoGetMetadataKeys(PVMFCPMCommand& aCmd)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::DoGetMetadataKeys Called"));
    if (iActivePlugInParamsVec.size() == 0)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataKeys - No Active Plugins"));
        return PVMFErrInvalidState;
    }

    iGetMetaDataKeysInProgress = true;

    if (iGetMetaDataKeysFromPlugInsDone == false)
    {
        if (CheckForMetaDataInterfaceAvailability())
        {
            PVMFStatus status = QueryForMetaDataKeys(aCmd);
            if (status != PVMFSuccess)
            {
                PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataKeys - QueryForMetaDataKeys Failed"));
                return status;
            }
            return PVMFPending;
        }
    }
    return (CompleteDoGetMetadataKeys(aCmd));
}
PVMFStatus
PVMFCPMImpl::CompleteDoGetMetadataKeys(PVMFCPMCommand& aCmd)
{
    iGetMetaDataKeysInProgress = false;

    PVMFMetadataList* keylistptr = NULL;
    int32 starting_index;
    int32 max_entries;
    char* query_key = NULL;

    aCmd.PVMFCPMCommand::Parse(keylistptr,
                               starting_index,
                               max_entries,
                               query_key);

    /* Check parameters */
    if ((keylistptr == NULL) ||
            (starting_index < 0)  ||
            (max_entries == 0))
    {
        /* Invalid starting index and/or max entries */
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteDoGetMetadataKeys - Invalid Args"));
        return PVMFErrArgument;
    }

    /* Copy the requested keys from all active plugins */
    uint32 num_entries = 0;
    int32 num_added = 0;
    int32 leavecode = 0;
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        it->iMetaDataKeyStartIndex = keylistptr->size();

        for (uint32 lcv = 0; lcv < it->iAvailableMetadataKeys.size(); lcv++)
        {
            if (query_key == NULL)
            {
                /* No query key so this key is counted */
                ++num_entries;
                if (num_entries > (uint32)starting_index)
                {
                    /* Past the starting index so copy the key */
                    leavecode = 0;
                    OSCL_TRY(leavecode, keylistptr->push_back(it->iAvailableMetadataKeys[lcv]));
                    OSCL_FIRST_CATCH_ANY(leavecode,
                                         PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteDoGetMetadataKeys() Memory allocation failure when copying metadata key"));
                                         return PVMFErrNoMemory);
                    num_added++;
                }
            }
            else
            {
                /* Check if the key matches the query key */
                if (pv_mime_strcmp((char*)it->iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
                {
                    /* This key is counted */
                    ++num_entries;
                    if (num_entries > (uint32)starting_index)
                    {
                        /* Past the starting index so copy the key */
                        leavecode = 0;
                        OSCL_TRY(leavecode, keylistptr->push_back(it->iAvailableMetadataKeys[lcv]));
                        OSCL_FIRST_CATCH_ANY(leavecode,
                                             PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteDoGetMetadataKeys() Memory allocation failure when copying metadata key"));
                                             return PVMFErrNoMemory);
                        num_added++;
                    }
                }
            }
            /* Check if max number of entries have been copied */
            if ((max_entries > 0) && (num_added >= max_entries))
            {
                break;
            }
        }
        it->iMetaDataValueEndIndex = keylistptr->size();
    }
    return PVMFSuccess;
}

void
PVMFCPMImpl::DoGetMetadataValues(PVMFCPMCommand& aCmd)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::DoGetMetadataValues Called"));
    MoveCmdToCurrentQueue(aCmd);

    if (iActivePlugInParamsVec.size() == 0)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataValues - No Active Plugins"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFErrInvalidState);
        return;
    }

    iKeyListPtr = NULL;
    iValueListPtr = NULL;
    iGetMetaDataValuesStartingIndex = 0;
    iGetMetaDataValuesMaxEntries = 0;


    aCmd.PVMFCPMCommand::Parse(iKeyListPtr,
                               iValueListPtr,
                               iGetMetaDataValuesStartingIndex,
                               iGetMetaDataValuesMaxEntries);

    /* Check the parameters */
    if (iKeyListPtr == NULL || iValueListPtr == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataValues - Null Args"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFErrArgument);
        return;
    }

    uint32 numkeys = iKeyListPtr->size();

    if ((iGetMetaDataValuesStartingIndex < 0) ||
            (iGetMetaDataValuesStartingIndex > (int32)(numkeys - 1)) ||
            ((int32)numkeys <= 0) ||
            (iGetMetaDataValuesMaxEntries == 0))
    {
        /* Don't do anything */
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataValues - Invalid Args"));
        CommandComplete(iCurrentCommand,
                        iCurrentCommand.front(),
                        PVMFErrArgument);
        return;
    }

    if (iActivePlugInParamsVec.size() > 0)
    {
        if (IsGetMetaDataValuesFromPlugInsComplete() == false)
        {
            CPMPlugInParams* plugInParams =
                LookUpNextPlugInForGetMetaDataValues();

            SendGetMetaDataValuesToPlugIn(plugInParams);
            return;
        }
        else
        {
            PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::DoGetMetadataValues - No Active Plugins With MetaData Support"));
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFSuccess);
            return;
        }
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetMetadataValues - No Active Plugins"));
    CommandComplete(iCurrentCommand,
                    iCurrentCommand.front(),
                    PVMFFailure);
    return;
}

CPMPlugInParams* PVMFCPMImpl::LookUpNextPlugInForGetMetaDataValues()
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iGetMetaDataValuesComplete == false)
        {
            return (it);
        }
    }
    return NULL;
}

bool PVMFCPMImpl::IsGetMetaDataValuesFromPlugInsComplete()
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInMetaDataExtensionInterface == NULL)
        {
            /* No metadata ext intf - so treat it as complete */
            it->iGetMetaDataValuesComplete = true;
        }
        else
        {
            if (it->iGetMetaDataValuesComplete == false)
            {
                return false;
            }
        }
    }
    return true;
}

void
PVMFCPMImpl::SendGetMetaDataValuesToPlugIn(CPMPlugInParams* aParams)
{
    if (aParams != NULL)
    {
        PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
        if (internalCmd != NULL)
        {
            internalCmd->cmd =
                PVMF_CPM_INTERNAL_GET_PLUGIN_META_DATA_VALUES_CMD;
            internalCmd->parentCmd = PVMF_CPM_GET_METADATA_VALUES;
            internalCmd->plugInID = aParams->iPlugInID;
            OsclAny *cmdContextData =
                OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

            aParams->iNumMetaDataValuesAvailable =
                aParams->iPlugInMetaDataExtensionInterface->GetNumMetadataValues((PVMFMetadataList&)(*iKeyListPtr));
            aParams->iMetaDataValueStartIndex = iValueListPtr->size();
            aParams->iPlugInMetaDataExtensionInterface->GetNodeMetadataValues(aParams->iPlugInSessionID,
                    (PVMFMetadataList&)(*iKeyListPtr),
                    (Oscl_Vector<PvmiKvp, OsclMemAllocator>&)(*iValueListPtr),
                    0,
                    aParams->iNumMetaDataValuesAvailable,
                    cmdContextData);
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::RequestMetaDataValues - SendGetMetaDataValuesToPlugIn Failed"));
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFErrNoMemory);
            return;
        }
    }
}

void
PVMFCPMImpl::CompleteGetMetaDataValues(PVMFCPMCommandContext* aContext)
{
    if (iActivePlugInParamsVec.size() > 0)
    {
        CPMPlugInParams* currPlugInParams =
            LookUpPlugInParamsFromActiveList(aContext->plugInID);
        OSCL_ASSERT(currPlugInParams);
        if (!currPlugInParams)
            return;	// unlikely: lookup failed.
        currPlugInParams->iMetaDataValueEndIndex = iValueListPtr->size();
        currPlugInParams->iGetMetaDataValuesComplete = true;

        if (IsGetMetaDataValuesFromPlugInsComplete() == false)
        {
            CPMPlugInParams* nextPlugInParams =
                LookUpNextPlugInForGetMetaDataValues();

            SendGetMetaDataValuesToPlugIn(nextPlugInParams);
        }
        else
        {
            /* Reset for future retrievals */
            Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
            for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
            {
                it->iGetMetaDataValuesComplete = false;
            }
            CommandComplete(iCurrentCommand,
                            iCurrentCommand.front(),
                            PVMFSuccess);
        }
        return;
    }
    /* No active plugins */
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::CompleteGetMetaDataValues - No Active Plugins"));
    CommandComplete(iCurrentCommand,
                    iCurrentCommand.front(),
                    PVMFFailure);
    return;
}

PVMFStatus PVMFCPMImpl::getParametersSync(PvmiMIOSession aSession,
        PvmiKeyType aIdentifier,
        PvmiKvp*& aParameters,
        int& num_parameter_elements,
        PvmiCapabilityContext aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aIdentifier);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_parameter_elements);
    OSCL_UNUSED_ARG(aContext);

    return PVMFErrNotSupported;
}


PVMFStatus PVMFCPMImpl::releaseParameters(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    PVMFStatus status = PVMFFailure;
    if (aParameters)
    {
        Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInCapConfigExtensionInterface != NULL)
            {
                status =
                    it->iPlugInCapConfigExtensionInterface->releaseParameters(aSession,
                            aParameters,
                            num_elements);
            }
        }
    }
    return status;
}


void PVMFCPMImpl::setParametersSync(PvmiMIOSession aSession,
                                    PvmiKvp* aParameters,
                                    int num_elements,
                                    PvmiKvp*& aRet_kvp)
{
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInCapConfigExtensionInterface != NULL)
        {
            int32 err;
            OSCL_TRY(err,
                     it->iPlugInCapConfigExtensionInterface->setParametersSync(aSession,
                             aParameters,
                             num_elements,
                             aRet_kvp););
            /* Ignore error - Not all plugins need support all config params */
        }
    }
}


PVMFStatus PVMFCPMImpl::verifyParametersSync(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    PVMFStatus status = PVMFFailure;
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
    {
        if (it->iPlugInCapConfigExtensionInterface != NULL)
        {
            status =
                it->iPlugInCapConfigExtensionInterface->verifyParametersSync(aSession,
                        aParameters,
                        num_elements);
        }
    }
    return status;
}
PVMFCommandId
PVMFCPMImpl::GetLicense(PVMFSessionId aSessionId,
                        OSCL_wString& aContentName,
                        OsclAny* aData,
                        uint32 aDataSize,
                        int32 aTimeoutMsec,
                        OsclAny* aContextData)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:GetLicense - Wide"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_GET_LICENSE_W,
                  aContentName,
                  aData,
                  aDataSize,
                  aTimeoutMsec,
                  aContextData);
    return QueueCommandL(cmd);
}

PVMFCommandId
PVMFCPMImpl::GetLicense(PVMFSessionId aSessionId,
                        OSCL_String&  aContentName,
                        OsclAny* aData,
                        uint32 aDataSize,
                        int32 aTimeoutMsec,
                        OsclAny* aContextData)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:GetLicense"));
    PVMFCPMCommand cmd;
    cmd.Construct(aSessionId,
                  PVMF_CPM_GET_LICENSE,
                  aContentName,
                  aData,
                  aDataSize,
                  aTimeoutMsec,
                  aContextData);
    return QueueCommandL(cmd);
}

PVMFCommandId
PVMFCPMImpl::CancelGetLicense(PVMFSessionId aSessionId, PVMFCommandId aCmdId, OsclAny* aContextData)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:CancelGetLicense"));
    PVMFCPMCommand cmd;
    cmd.PVMFCPMCommandBase::Construct(aSessionId,
                                      PVMF_CPM_CANCEL_GET_LICENSE,
                                      aCmdId,
                                      aContextData);
    return QueueCommandL(cmd);
}

PVMFStatus PVMFCPMImpl::GetLicenseStatus(
    PVMFCPMLicenseStatus& aStatus)
{
    if (iLicenseInterface)
        return iLicenseInterface->GetLicenseStatus(aStatus);
    return PVMFFailure;
}

PVMFStatus PVMFCPMImpl::DoGetLicense(PVMFCPMCommand& aCmd,
                                     bool aWideCharVersion)
{
    iLicenseInterface = NULL;
    CPMSessionInfo* sInfo = LookUpSessionInfo(aCmd.iSession);
    CPMPlugInParams* pluginParamsPtr = NULL;
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    if (sInfo != NULL)
    {
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                iLicenseInterface = it->iPlugInLicenseInterface;
                pluginParamsPtr = it;
            }
        }
    }

    if (iLicenseInterface == NULL)
    {
        PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetLicense - No License Interface"));
        return PVMFErrNotSupported;
    }

    if (aWideCharVersion == true)
    {
        OSCL_wString* contentName = NULL;
        OsclAny* data = NULL;
        uint32 dataSize = 0;
        int32 timeoutMsec = 0;
        aCmd.Parse(contentName,
                   data,
                   dataSize,
                   timeoutMsec);

        PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
        if (internalCmd != NULL)
        {
            internalCmd->cmd = PVMF_CPM_INTERNAL_GET_LICENSE_CMD;
            internalCmd->parentCmd = PVMF_CPM_GET_LICENSE_W;
            internalCmd->plugInID = pluginParamsPtr->iPlugInID;
            OsclAny *cmdContextData =
                OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
            iGetLicenseCmdId =
                iLicenseInterface->GetLicense(pluginParamsPtr->iPlugInSessionID,
                                              *contentName,
                                              data,
                                              dataSize,
                                              timeoutMsec,
                                              cmdContextData);
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetLicense - RequestNewInternalCmd Failed"));
            return PVMFErrNoMemory;
        }
    }
    else
    {
        OSCL_String* contentName = NULL;
        OsclAny* data = NULL;
        uint32 dataSize = 0;
        int32 timeoutMsec = 0;
        aCmd.Parse(contentName,
                   data,
                   dataSize,
                   timeoutMsec);
        PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
        if (internalCmd != NULL)
        {
            internalCmd->cmd = PVMF_CPM_INTERNAL_GET_LICENSE_CMD;
            internalCmd->parentCmd = PVMF_CPM_GET_LICENSE;
            internalCmd->plugInID = pluginParamsPtr->iPlugInID;
            OsclAny *cmdContextData =
                OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);
            iGetLicenseCmdId =
                iLicenseInterface->GetLicense(pluginParamsPtr->iPlugInSessionID,
                                              *contentName,
                                              data,
                                              dataSize,
                                              timeoutMsec,
                                              cmdContextData);
        }
        else
        {
            PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoGetLicense - RequestNewInternalCmd Failed"));
            return PVMFErrNoMemory;
        }
    }
    return PVMFPending;
}

void PVMFCPMImpl::CompleteGetLicense()
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl::CompleteGetLicense - Success"));
    CommandComplete(iCurrentCommand,
                    iCurrentCommand.front(),
                    PVMFSuccess);
}

void PVMFCPMImpl::DoCancelGetLicense(PVMFCPMCommand& aCmd)
{
    PVMF_CPM_LOGINFO((0, "PVMFCPMImpl:DoCancelGetLicense is called"));
    /* extract the command ID from the parameters.*/
    PVMFCommandId id;
    aCmd.PVMFCPMCommandBase::Parse(id);
    PVMFStatus status = PVMFErrArgument;

    iLicenseInterface = NULL;
    CPMSessionInfo* sInfo = LookUpSessionInfo(aCmd.iSession);
    CPMPlugInParams* pluginParamsPtr = NULL;
    Oscl_Vector<CPMPlugInParams, OsclMemAllocator>::iterator it;
    if (sInfo != NULL)
    {
        for (it = iActivePlugInParamsVec.begin(); it != iActivePlugInParamsVec.end(); it++)
        {
            if (it->iPlugInID == sInfo->iAccessPlugInID)
            {
                iLicenseInterface = it->iPlugInLicenseInterface;
                pluginParamsPtr = it;
            }
        }
    }

    /* first check "current" command if any */
    PVMFCPMCommand* cmd = iCurrentCommand.FindById(id);
    if (cmd)
    {
        if (cmd->iCmd == PVMF_CPM_GET_LICENSE_W || cmd->iCmd == PVMF_CPM_GET_LICENSE)
        {
            PVMFCPMCommandContext* internalCmd = RequestNewInternalCmd();
            if (internalCmd != NULL)
            {
                internalCmd->cmd = PVMF_CPM_INTERNAL_CANCEL_GET_LICENSE;
                internalCmd->parentCmd = PVMF_CPM_CANCEL_GET_LICENSE;
                internalCmd->plugInID = pluginParamsPtr->iPlugInID;
                OsclAny *cmdContextData =
                    OSCL_REINTERPRET_CAST(OsclAny*, internalCmd);

                iLicenseInterface->CancelGetLicense(pluginParamsPtr->iPlugInSessionID, iGetLicenseCmdId, cmdContextData);

                /*
                 * the queued commands are all asynchronous commands to the
                 * CPM module. CancelGetLicense can cancel only for GetLicense cmd.
                 * We need to wait CPMPluginCommandCompleted.
                 */
                MoveCmdToCancelQueue(aCmd);
                return;
            }
            else
            {
                PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoCancelGetLicense - RequestNewInternalCmd Failed"));
                status = PVMFErrNoMemory;
            }
        }
    }
    PVMF_CPM_LOGERROR((0, "PVMFCPMImpl::DoCancelGetLicense - current cmd is not GetLicense"));
    CommandComplete(iInputCommands, aCmd, status);
    return;
}

OSCL_EXPORT_REF bool CPMPluginRegistryImpl::addPluginToRegistry(OSCL_String& aMimeType,
        CPMPluginContainer& aPlugInContainer)
{
    CPMPluginContainer*container = lookupPlugin(aMimeType);
    if (container)
        return false;//duplicate mime type!
    container = OSCL_NEW(CPMPluginContainer, (aPlugInContainer));
    iCPMPluginRegistry.insert(value_type(aMimeType, container));
    iListofPlugInMimeTypes.push_back(aMimeType);
    return true;
}

OSCL_EXPORT_REF void CPMPluginRegistryImpl::removePluginFromRegistry(OSCL_String& aMimeType)
{
    CPMPluginContainer*container = lookupPlugin(aMimeType);
    if (container)
    {
        OSCL_DELETE(container);
    }
    for (uint32 i = 0;i < iListofPlugInMimeTypes.size();i++)
    {
        if (iListofPlugInMimeTypes[i] == aMimeType)
        {
            iListofPlugInMimeTypes.erase(&iListofPlugInMimeTypes[i]);
            iCPMPluginRegistry.erase(iCPMPluginRegistry.find(aMimeType));
        }
    }
}

OSCL_EXPORT_REF CPMPluginContainer* CPMPluginRegistryImpl::lookupPlugin(OSCL_String& aMimeType)
{
    Oscl_Map<string_key_type, CPMPluginContainer*, OsclMemAllocator, string_key_compare_class>::iterator it;
    it = iCPMPluginRegistry.find(aMimeType);

    if (!(it == iCPMPluginRegistry.end()))
    {
        return (((*it).second));
    }
    return NULL;
}

OSCL_EXPORT_REF uint32 CPMPluginRegistryImpl::GetNumPlugIns()
{
    return (iCPMPluginRegistry.size());
}

OSCL_EXPORT_REF bool CPMPluginRegistryImpl::GetPluginMimeType(uint32 aIndex, OSCL_String& aMimeType)
{
    if (aIndex < GetNumPlugIns())
    {
        aMimeType = iListofPlugInMimeTypes[aIndex];
        return true;
    }
    return false;//invalid index.
}

OSCL_EXPORT_REF CPMPluginRegistryImpl::CPMPluginRegistryImpl()
{
    iRefCount = 0;
}

OSCL_EXPORT_REF CPMPluginRegistryImpl::~CPMPluginRegistryImpl()
{
    //just in case plugins weren't removed, go through and cleanup
    for (uint32 i = 0;i < iListofPlugInMimeTypes.size();i++)
    {
        CPMPluginContainer* container = lookupPlugin(iListofPlugInMimeTypes[i]);
        if (container)
            OSCL_DELETE(container);
    }
}

CPMPluginRegistry* CPMPluginRegistryFactory::CreateCPMPluginRegistry()
{
    return (CPMPluginRegistry*)OSCL_NEW(CPMPluginRegistryImpl, ());
}

void CPMPluginRegistryFactory::DestroyCPMPluginRegistry(CPMPluginRegistry* aReg)
{
    CPMPluginRegistryImpl* impl = (CPMPluginRegistryImpl*)aReg;
    OSCL_DELETE(impl);
}

