/**
        Get the value for the spcified resource from a specified instance

        \param[in]     resource      Name of resource to get
        \param[in]     processinst   Instance to get resource from

        \returns       Value for specifed resource

        \throws        SCXInternalErrorException    If given resource not handled
    */
    scxulong ProcessProvider::GetResource(const std::wstring &resource, SCXCoreLib::SCXHandle<SCXSystemLib::ProcessInstance> processinst)
    {
        scxulong res = 0;
        bool gotResource = false;

        if (StrCompare(resource, L"CPUTime", true) == 0)
        {
            unsigned int cputime;
            gotResource = processinst->GetCPUTime(cputime);
            res = static_cast<scxulong>(cputime);
        }
        else if (StrCompare(resource, L"BlockReadsPerSecond", true) == 0)
        {
            gotResource = processinst->GetBlockReadsPerSecond(res);
        }
        else if (StrCompare(resource, L"BlockWritesPerSecond", true) == 0)
        {
            gotResource = processinst->GetBlockWritesPerSecond(res);
        }
        else if (StrCompare(resource, L"BlockTransfersPerSecond", true) == 0)
        {
            gotResource = processinst->GetBlockTransfersPerSecond(res);
        }
        else if (StrCompare(resource, L"PercentUserTime", true) == 0)
        {
            gotResource = processinst->GetPercentUserTime(res);
        }
        else if (StrCompare(resource, L"PercentPrivilegedTime", true) == 0)
        {
            gotResource = processinst->GetPercentPrivilegedTime(res);
        }
        else if (StrCompare(resource, L"UsedMemory", true) == 0)
        {
            gotResource = processinst->GetUsedMemory(res);
        }
        else if (StrCompare(resource, L"PercentUsedMemory", true) == 0)
        {
            gotResource = processinst->GetPercentUsedMemory(res);
        }
        else if (StrCompare(resource, L"PagesReadPerSec", true) == 0)
        {
            gotResource = processinst->GetPagesReadPerSec(res);
        }
        else
        {
            throw UnknownResourceException(resource, SCXSRCLOCATION);
        }

        if ( ! gotResource)
        {
            throw SCXInternalErrorException(StrAppend(L"GetResource: Failed to get resouce: ", resource), SCXSRCLOCATION);
        }

        return res;
    }
    /**
       Set all properties from the ProcessInstance in the SCXInstance

       \param[in]  processinst  - Process instance to get data from
       \param[in]  inst         - Instance to populate
       \param[in]  cimtype      - Type of CIM Class to return

       \throws      SCXInvalidArgumentException - If the instance can not be converted to a ProcessInstance

       This method knows how to map the values of the Process PAL to the CMPI class
       definition.

    */
    void ProcessProvider::AddProperties(SCXCoreLib::SCXHandle<SCXSystemLib::ProcessInstance> processinst, SCXInstance &inst, SupportedCimClasses cimtype) // private
    {
        if (processinst == NULL)
        {
            throw SCXInvalidArgumentException(L"einst", L"Not a ProcessInstance", SCXSRCLOCATION);
        }

        SCX_LOGTRACE(m_log, L"ProcessProvider AddPropeties()");

        if (eSCX_UnixProcessStatisticalInformation == cimtype)
        {
            unsigned int uint = 0;
            scxulong ulong = 0;

            if (processinst->GetRealData(ulong))
            {
                SCXProperty prop(L"RealData", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetRealStack(ulong))
            {
                SCXProperty prop(L"RealStack", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetVirtualText(ulong))
            {
                SCXProperty prop(L"VirtualText", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetVirtualData(ulong))
            {
                SCXProperty prop(L"VirtualData", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetVirtualStack(ulong))
            {
                SCXProperty prop(L"VirtualStack", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetVirtualMemoryMappedFileSize(ulong))
            {
                SCXProperty prop(L"VirtualMemoryMappedFileSize", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetVirtualSharedMemory(ulong))
            {
                SCXProperty prop(L"VirtualSharedMemory", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetCpuTimeDeadChildren(ulong))
            {
                SCXProperty prop(L"CpuTimeDeadChildren", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetSystemTimeDeadChildren(ulong))
            {
                SCXProperty prop(L"SystemTimeDeadChildren", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetRealText(ulong))
            {
                SCXProperty prop(L"RealText", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetCPUTime(uint))
            {
                SCXProperty prop(L"CPUTime", uint);
                inst.AddProperty(prop);
            }

            if (processinst->GetBlockWritesPerSecond(ulong))
            {
                SCXProperty prop(L"BlockWritesPerSecond", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetBlockReadsPerSecond(ulong))
            {
                SCXProperty prop(L"BlockReadsPerSecond", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetBlockTransfersPerSecond(ulong))
            {
                SCXProperty prop(L"BlockTransfersPerSecond", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetPercentUserTime(ulong))
            {
                SCXProperty prop(L"PercentUserTime", (unsigned char) ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetPercentPrivilegedTime(ulong))
            {
                SCXProperty prop(L"PercentPrivilegedTime", (unsigned char) ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetUsedMemory(ulong))
            {
                SCXProperty prop(L"UsedMemory", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetPercentUsedMemory(ulong))
            {
                SCXProperty prop(L"PercentUsedMemory", (unsigned char) ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetPagesReadPerSec(ulong))
            {
                SCXProperty prop(L"PagesReadPerSec", ulong);
                inst.AddProperty(prop);
            }
        }
        else if (eSCX_UnixProcess == cimtype)
        {
            std::string name("");
            std::vector<std::string> params;
            std::wstring str(L"");
            unsigned int uint = 0;
            unsigned short ushort = 0;
            scxulong ulong = 0;
            SCXCoreLib::SCXCalendarTime ctime;
            int pid = 0;

            if (processinst->GetOtherExecutionDescription(str))
            {
                SCXProperty prop(L"OtherExecutionDescription", str);
                inst.AddProperty(prop);
            }

            if (processinst->GetKernelModeTime(ulong))
            {
                SCXProperty prop(L"KernelModeTime", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetUserModeTime(ulong))
            {
                SCXProperty prop(L"UserModeTime", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetWorkingSetSize(ulong))
            {
                SCXProperty prop(L"WorkingSetSize", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetProcessSessionID(ulong))
            {
                SCXProperty prop(L"ProcessSessionID", ulong);
                inst.AddProperty(prop);
            }

            if (processinst->GetProcessTTY(name))
            {
                SCXProperty prop(L"ProcessTTY", StrFromMultibyte(name));
                inst.AddProperty(prop);
            }

            if (processinst->GetModulePath(name))
            {
                SCXProperty prop(L"ModulePath", StrFromMultibyte(name));
                inst.AddProperty(prop);
            }

            if (processinst->GetParameters(params))
            {
                std::vector<SCXProperty> props;
                for (std::vector<std::string>::const_iterator iter = params.begin();
                     iter != params.end(); ++iter)
                {
                    SCXProperty item(L"", StrFromMultibyte(*iter));
                    props.push_back(item);
                }
                SCXProperty prop(L"Parameters", props);
                inst.AddProperty(prop);
            }

            if (processinst->GetProcessWaitingForEvent(name))
            {
                SCXProperty prop(L"ProcessWaitingForEvent", StrFromMultibyte(name));
                inst.AddProperty(prop);
            }

            if (processinst->GetName(name))
            {
                SCXProperty name_prop(L"Name", StrFromMultibyte(name));
                inst.AddProperty(name_prop);
            }

            if (processinst->GetPriority(uint))
            {
                SCXProperty prio_prop(L"Priority", uint);
                inst.AddProperty(prio_prop);
            }

            if (processinst->GetExecutionState(ushort))
            {
                SCXProperty state_prop(L"ExecutionState", ushort);
                inst.AddProperty(state_prop);
            }

            if (processinst->GetCreationDate(ctime))
            {
                SCXProperty cdate_prop(L"CreationDate", ctime);
                inst.AddProperty(cdate_prop);
            }

            if (processinst->GetTerminationDate(ctime))
            {
                SCXProperty edate_prop(L"TerminationDate", ctime);
                inst.AddProperty(edate_prop);
            }

            if (processinst->GetParentProcessID(pid))
            {
                SCXProperty ppid_prop(L"ParentProcessID", StrFrom(pid));
                inst.AddProperty(ppid_prop);
            }

            if (processinst->GetRealUserID(ulong))
            {
                SCXProperty user_prop(L"RealUserID", ulong);
                inst.AddProperty(user_prop);
            }

            if (processinst->GetProcessGroupID(ulong))
            {
                SCXProperty group_prop(L"ProcessGroupID", ulong);
                inst.AddProperty(group_prop);
            }

            if (processinst->GetProcessNiceValue(uint))
            {
                SCXProperty nice_prop(L"ProcessNiceValue", uint);
                inst.AddProperty(nice_prop);
            }
        }

    }
MI_BEGIN_NAMESPACE

static void EnumerateOneInstance(Context& context,
        SCX_UnixProcessStatisticalInformation_Class& inst, bool keysOnly,
        SCXCoreLib::SCXHandle<SCXSystemLib::ProcessInstance> processinst)
{
    SCXLogHandle& log = SCXCore::g_ProcessProvider.GetLogHandle();

    // Add the key properties first.
    scxulong pid;
    if (processinst->GetPID(pid))
    {
        inst.Handle_value(StrToUTF8(StrFrom(pid)).c_str());
    }

    // Add keys of scoping operating system
    try {
        SCXCoreLib::NameResolver mi;
        inst.CSName_value(StrToMultibyte(mi.GetHostDomainname()).c_str());
    } catch (SCXException& e){
        SCX_LOGWARNING(log, StrAppend(
                    StrAppend(L"Can't read host/domainname because ", e.What()),
                    e.Where()));
    }

    try {
        SCXSystemLib::SCXOSTypeInfo osinfo;
        inst.OSName_value(StrToMultibyte(osinfo.GetOSName(true)).c_str());
    } catch (SCXException& e){
        SCX_LOGWARNING(log, StrAppend(
                    StrAppend(L"Can't read OS name because ", e.What()),
                    e.Where()));
    }

    inst.CSCreationClassName_value("SCX_ComputerSystem");
    inst.OSCreationClassName_value("SCX_OperatingSystem");
    inst.ProcessCreationClassName_value("SCX_UnixProcessStatisticalInformation");

    std::string name;
    if (processinst->GetName(name))
    {
        inst.Name_value(name.c_str());
    }

    if (!keysOnly)
    {
        unsigned int uint = 0;
        scxulong ulong = 0;

        inst.Description_value("A snapshot of a current process");
        inst.Caption_value("Unix process information");

        if (processinst->GetRealData(ulong))
        {
            inst.RealData_value(ulong);
        }

        if (processinst->GetRealStack(ulong))
        {
            inst.RealStack_value(ulong);
        }

        if (processinst->GetVirtualText(ulong))
        {
            inst.VirtualText_value(ulong);
        }

        if (processinst->GetVirtualData(ulong))
        {
            inst.VirtualData_value(ulong);
        }

        if (processinst->GetVirtualStack(ulong))
        {
            inst.VirtualStack_value(ulong);
        }

        if (processinst->GetVirtualMemoryMappedFileSize(ulong))
        {
            inst.VirtualMemoryMappedFileSize_value(ulong);
        }

        if (processinst->GetVirtualSharedMemory(ulong))
        {
            inst.VirtualSharedMemory_value(ulong);
        }

        if (processinst->GetCpuTimeDeadChildren(ulong))
        {
            inst.CpuTimeDeadChildren_value(ulong);
        }

        if (processinst->GetSystemTimeDeadChildren(ulong))
        {
            inst.SystemTimeDeadChildren_value(ulong);
        }

        if (processinst->GetRealText(ulong))
        {
            inst.RealText_value(ulong);
        }

        if (processinst->GetCPUTime(uint))
        {
            inst.CPUTime_value(uint);
        }

        if (processinst->GetBlockWritesPerSecond(ulong))
        {
            inst.BlockWritesPerSecond_value(ulong);
        }

        if (processinst->GetBlockReadsPerSecond(ulong))
        {
            inst.BlockReadsPerSecond_value(ulong);
        }

        if (processinst->GetBlockTransfersPerSecond(ulong))
        {
            inst.BlockTransfersPerSecond_value(ulong);
        }

        if (processinst->GetPercentUserTime(ulong))
        {
            inst.PercentUserTime_value((unsigned char) ulong);
        }

        if (processinst->GetPercentPrivilegedTime(ulong))
        {
            inst.PercentPrivilegedTime_value((unsigned char) ulong);
        }

        if (processinst->GetUsedMemory(ulong))
        {
            inst.UsedMemory_value(ulong);
        }

        if (processinst->GetPercentUsedMemory(ulong))
        {
            inst.PercentUsedMemory_value((unsigned char) ulong);
        }

        if (processinst->GetPagesReadPerSec(ulong))
        {
            inst.PagesReadPerSec_value(ulong);
        }
    }
    context.Post(inst);
}