void mtsManagerComponentServer::InterfaceGCMCommands_ComponentGetState(const mtsDescriptionComponent &component,
                                                                       mtsComponentState &state) const
{
    // Check if command is for this component (MCS)
    if (component.ComponentName == this->GetName()) {
        //GetState(state);
        //For now, always return active for MCC
        state = mtsComponentState::ACTIVE;
        return;
    }
    if (!GCM->FindComponent(component.ProcessName, component.ComponentName)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentGetState: failed to get component state - no component found: "
                                << component << std::endl;
        return;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(component.ProcessName, CMN_LOG_LEVEL_NONE);
    if (!functionSet) {
        state = mtsComponentState::INITIALIZING;
        CMN_LOG_CLASS_RUN_WARNING << "InterfaceGCMCommands_ComponentGetState: failed to get function set: " << component << std::endl;
        return;
    }
    if (!functionSet->ComponentGetState.IsValid()) {
        state = mtsComponentState::INITIALIZING;
        CMN_LOG_CLASS_RUN_WARNING << "InterfaceGCMCommands_ComponentGetState: failed to execute \"Component GetState\"" << std::endl;
        return;
    }

    functionSet->ComponentGetState(component, state);
}
void mtsManagerComponentServer::InterfaceGCMCommands_ComponentCreate(const mtsDescriptionComponent & componentDescription, bool & result)
{
    // Check if a new component with the name specified can be created
    if (GCM->FindComponent(componentDescription.ProcessName,
                           componentDescription.ComponentName)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentCreate: failed to create component: " << componentDescription << std::endl
                                << "InterfaceGCMCommands_ComponentCreate: component already exists" << std::endl;
        result = false;
        return;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(componentDescription.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentCreate: failed to execute \"Component Create\": " << componentDescription << std::endl;
        result = false;
        return;
    }

    mtsExecutionResult executionResult = functionSet->ComponentCreate(componentDescription, result);
    if (!executionResult.IsOK()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentCreate: failed to execute \"ComponentCreate\": " << componentDescription << std::endl
                                << " error \"" << executionResult << "\"" << std::endl;
        result = false;
    }
}
void mtsManagerComponentServer::InterfaceGCMCommands_ComponentResume(const mtsComponentStatusControl & arg)
{
    // Check if command is for this component (MCS)
    if (arg.ComponentName == this->GetName()) {
        CMN_LOG_CLASS_RUN_WARNING << "ComponentResume for " << arg.ComponentName << " ignored." << std::endl;
        return;
    }
    // Check if a new component with the name specified can be created
    if (!GCM->FindComponent(arg.ProcessName, arg.ComponentName)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentResume: failed to Resume component - no component found: " << arg << std::endl;
        return;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(arg.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentResume: failed to get function set: " << arg << std::endl;
        return;
    }
    if (!functionSet->ComponentResume.IsValid()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentResume: failed to execute \"Component Resume\"" << std::endl;
        return;
    }

    //functionSet->ComponentResume.ExecuteBlocking(arg);
    functionSet->ComponentResume(arg);
}
// Internal command
void mtsManagerComponentServer::InterfaceGCMCommands_SetLogForwarding(const std::vector<std::string> & processNames, bool state)
{
    for (unsigned int i = 0; i < processNames.size(); i++) {
        InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processNames[i], CMN_LOG_LEVEL_NONE);
        if (functionSet)
            functionSet->SetLogForwarding(state);
        else
            CMN_LOG_CLASS_RUN_ERROR << "SetLogForwarding: could not find functions for process " << processNames[i] << std::endl;
    }
}
void mtsManagerComponentServer::ComponentDisconnect(const std::string & processName, const mtsDescriptionConnection & arg)
{
    // Get a set of function objects that are bound to the InterfaceLCM's provided interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "ComponentDisconnect: failed to get function set for process \""
            << processName << "\": " << arg << std::endl;
        return;
    }

    //functionSet->ComponentDisconnect.ExecuteBlocking(arg);
    functionSet->ComponentDisconnect(arg);
}
// MJ: Another method that does the same thing but accepts a single parameter
// as connection id should be added.
void mtsManagerComponentServer::InterfaceGCMCommands_ComponentDisconnect(const mtsDescriptionConnection & arg)
{
    if (!GCM->Disconnect(arg)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentDisconnect: failed to execute \"Component Disconnect\" for: " << arg << std::endl;
        return;
    }

#if 0
    InterfaceGCMFunctionType *functionSet;
    if (arg.Client.ProcessName != arg.Server.ProcessName) {
        // PK TEMP fix for network disconnect
        mtsDescriptionConnection arg2;
        // Step 1: Disconnect Client from ServerProxy
        CMN_LOG_CLASS_RUN_WARNING << "Network disconnect for " << arg << ", step 1 (client side disconnect)" << std::endl;
        arg2 = arg;
        arg2.Server.ProcessName = arg.Client.ProcessName;
        arg2.Server.ComponentName = mtsManagerGlobal::GetComponentProxyName(arg.Server.ProcessName, arg.Server.ComponentName);
        functionSet = InterfaceGCMFunctionMap.GetItem(arg2.Client.ProcessName);
        if (!functionSet) {
            CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentDisconnect: failed to get function set for " << arg2.Client.ProcessName << std::endl;
            return;
        }
        functionSet->ComponentDisconnect(arg2);
        // Step 2: Disconnect ClientProxy from Server
        CMN_LOG_CLASS_RUN_WARNING << "Network disconnect for " << arg << ", step 2 (server side disconnect)" << std::endl;
        arg2 = arg;
        arg2.Client.ProcessName = arg.Server.ProcessName;
        arg2.Client.ComponentName = mtsManagerGlobal::GetComponentProxyName(arg.Client.ProcessName, arg.Client.ComponentName);
        functionSet = InterfaceGCMFunctionMap.GetItem(arg2.Server.ProcessName);
        if (!functionSet) {
            CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentDisconnect: failed to get function set for " << arg2.Server.ProcessName << std::endl;
            return;
        }
        functionSet->ComponentDisconnect(arg2);
        // Step 3: Update the GCM database (send arg unchanged to any MCC)
        // For now, we just fall through to the statement below
        CMN_LOG_CLASS_RUN_WARNING << "Network disconnect for " << arg << ", step 3 (update GCM)" << std::endl;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    functionSet = InterfaceGCMFunctionMap.GetItem(arg.Client.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentDisconnect: failed to execute \"Component Disconnect\": " << arg << std::endl;
        return;
    }

    //functionSet->ComponentDisconnect.ExecuteBlocking(arg);
    functionSet->ComponentDisconnect(arg);
#endif
}
void mtsManagerComponentServer::InterfaceGCMCommands_GetLogForwardingStates(const stdStringVec & processNames, stdCharVec & states) const
{
    states.resize(processNames.size());

    bool state;
    for (unsigned int i = 0; i < processNames.size(); i++) {
        InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processNames[i], CMN_LOG_LEVEL_NONE);
        if (functionSet) {
            functionSet->GetLogForwardingState(state);
            states[i] = (state ? 1 : 0);
        }
        else
            CMN_LOG_CLASS_RUN_ERROR << "GetLogForwardingStates: could not find functions for process " << processNames[i] << std::endl;
    }
}
void mtsManagerComponentServer::InterfaceGCMCommands_GetAbsoluteTimeDiffs(const std::vector<std::string> & processNames,
                                                                          std::vector<double> & processTimes) const
{
    double sleepTime = 0.1;
    unsigned int numOfTrials = 10;

    vctDynamicVector<double> trialTimes(numOfTrials);

    double time;
    mtsExecutionResult result;

    // Make sure return vector has correct size
    processTimes.resize(processNames.size());

    mtsManagerLocal * LCM = mtsManagerLocal::GetInstance();
    const std::string thisProcess = LCM->GetProcessName();

    for (unsigned int i = 0; i < processNames.size(); i++) {

        processTimes[i] = 0.0;
        if (processNames[i] == thisProcess)
            continue;

        InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processNames[i], CMN_LOG_LEVEL_NONE);
        if (!functionSet) {
            CMN_LOG_CLASS_RUN_ERROR << "GetAbsoluteTimeDiffs: could not find functions for process " << processNames[i] << std::endl;
            continue;
        }

        trialTimes.Zeros();
        for (unsigned int t = 0; t < numOfTrials; t++) {
            double tic = LCM->GetTimeServer().GetAbsoluteTimeInSeconds();
            result = functionSet->GetAbsoluteTimeInSeconds(time);
            double roundTripTime =  LCM->GetTimeServer().GetAbsoluteTimeInSeconds() - tic;
            if (result.IsOK()) {
                trialTimes[i] = (tic + roundTripTime/2.0) - time;
            }
            else {
                CMN_LOG_CLASS_RUN_ERROR << "GetAbsoluteTimeDiffs: could not execute command for process " << processNames[i]
                                        << ", result = " << result << std::endl;
                trialTimes.Zeros();
                break;
            }
            osaSleep(sleepTime);
        }
        processTimes[i] = trialTimes.SumOfElements()/numOfTrials;
    }
}
void mtsManagerComponentServer::InterfaceGCMCommands_GetListOfComponentClasses(const std::string & processName,
                                std::vector<mtsDescriptionComponentClass> & listOfComponentClasses) const
{
    // Get a set of function objects that are bound to the InterfaceLCM's provided interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_GetListOfComponentClasses: failed to get function set for "
                                << processName << std::endl;
        return;
    }
    if (!functionSet->GetListOfComponentClasses.IsValid()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_GetListOfComponentClasses: function not bound to command" << std::endl;
        return;
    }

    functionSet->GetListOfComponentClasses(listOfComponentClasses);
}
void mtsManagerComponentServer::InterfaceGCMCommands_LoadLibrary(const mtsDescriptionLoadLibrary &lib,
                                                                       bool &result) const
{
    // Get a set of function objects that are bound to the InterfaceLCM's provided interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(lib.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_LoadLibrary: failed to get function set: " << lib << std::endl;
        result = false;
        return;
    }
    if (!functionSet->LoadLibrary.IsValid()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_LoadLibrary: function not bound to command" << std::endl;
        result = false;
        return;
    }

    functionSet->LoadLibrary(lib.LibraryName, result);
}
bool mtsManagerComponentServer::ComponentDisconnect(const std::string & processName, const mtsDescriptionConnection & arg)
{
    // Get a set of function objects that are bound to the InterfaceLCM's provided interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(processName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "ComponentDisconnect: failed to get function set for process \""
            << processName << "\": " << arg << std::endl;
        return false;
    }

    bool result = true;
#if CISST_MTS_NEW
    //functionSet->ComponentDisconnectNew(arg, result);
    result = false;   // PK HACK: actually works better if we don't call ComponentDisconnect or ComponentDisconnectNew
#else
    //functionSet->ComponentDisconnect.ExecuteBlocking(arg);
    functionSet->ComponentDisconnect(arg);
#endif
    return result;
}
void mtsManagerComponentServer::InterfaceGCMCommands_GetInterfaceRequiredDescription(const mtsDescriptionInterface & intfc,
                                                                                     mtsInterfaceRequiredDescription & description) const
{
    if (!GCM->FindComponent(intfc.ProcessName, intfc.ComponentName)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_GetInterfaceRequiredDescription: failed to get interface description - no component found: "
                                << intfc.ProcessName << ":" << intfc.ComponentName << std::endl;
        return;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(intfc.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_GetInterfaceRequiredDescription: failed to get function set for "
                                << intfc.ProcessName << std::endl;
        return;
    }
    if (!functionSet->GetInterfaceRequiredDescription.IsValid()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_GetInterfaceRequiredDescription: function not bound to command" << std::endl;
        return;
    }

    functionSet->GetInterfaceRequiredDescription(intfc, description);
}
void mtsManagerComponentServer::InterfaceGCMCommands_ComponentConnectNew(const mtsDescriptionConnection & connectionDescription, bool & result)
{
    // We don't check argument validity with the GCM at this stage and rely on
    // the current normal connection procedure (GCM allows connection at the
    // request of LCM) because the GCM guarantees that arguments are valid.
    // The Connect request is then passed to the manager component client which
    // calls local component manager's Connect() method.

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(connectionDescription.Client.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentConnect: failed to execute \"Component Connect\": " << connectionDescription << std::endl;
        result = false;
        return;
    }
    mtsExecutionResult executionResult =  functionSet->ComponentConnectNew(connectionDescription, result);
    if (!executionResult.IsOK()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentConnect: failed to execute \"ComponentConnect\": " << connectionDescription << std::endl
                                << " error \"" << executionResult << "\"" << std::endl;
        result = false;
    }
}
void mtsManagerComponentServer::InterfaceGCMCommands_ComponentConfigure(const mtsDescriptionComponent & arg)
{
    // Check if component with the name specified can be found
    if (!GCM->FindComponent(arg.ProcessName, arg.ComponentName)) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentConfigure - no component found: " << arg << std::endl;
        return;
    }

    // Get a set of function objects that are bound to the InterfaceLCM's provided
    // interface.
    InterfaceGCMFunctionType * functionSet = InterfaceGCMFunctionMap.GetItem(arg.ProcessName);
    if (!functionSet) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentConfigure: failed to execute \"Component Configure\": " << arg << std::endl;
        return;
    }

    if (!functionSet->ComponentConfigure.IsValid()) {
        CMN_LOG_CLASS_RUN_ERROR << "InterfaceGCMCommands_ComponentConfigure: function not bound to command" << std::endl;
        return;
    }

    //functionSet->ComponentConfigure.ExecuteBlocking(arg);
    functionSet->ComponentConfigure(arg);
}