MI_BEGIN_NAMESPACE

static void EnumerateOneInstance(
    Context& context,
    SCX_MemoryStatisticalInformation_Class& inst,
    bool keysOnly,
    SCXCoreLib::SCXHandle<SCXSystemLib::MemoryInstance> meminst)
{
    // Populate the key values
    inst.Name_value("Memory");

    if (!keysOnly)
    {
        scxulong physmem = 0;
        scxulong resmem = 0;
        scxulong usermem = 0;
        scxulong avail = 0;
        scxulong data = 0;
        scxulong data2 = 0;

        inst.Caption_value("Memory information");
        inst.Description_value("Memory usage and performance statistics");

        inst.IsAggregate_value(meminst->IsTotal());

        if (meminst->GetTotalPhysicalMemory(physmem))
        {
            // Adjust numbers from PAL to Megabytes
            physmem = BytesToMegaBytes(physmem);

            if (meminst->GetReservedMemory(resmem))
            {
                resmem = BytesToMegaBytes(resmem);
            }
            else
            {
                resmem = 0;
            }

            // If available, get memory unavailable for user processes and remove it from physical memory
            usermem = physmem - resmem;
        }

        if (meminst->GetAvailableMemory(avail))
        {
            // Adjust numbers from PAL to Megabytes
            avail = BytesToMegaBytes(avail);
            inst.AvailableMemory_value(avail);

            // If we have a number for physical memory use it to compute a percentage
            if (usermem > 0)
            {
                // Need an unsigned char since this is what is required by the MOF
                unsigned char percent = static_cast<unsigned char> (GetPercentage(0, avail, 0, usermem));
                inst.PercentAvailableMemory_value(percent);
            }
        }

        if (meminst->GetUsedMemory(data))
        {
            // Adjust numbers from PAL to Megabytes
            data = BytesToMegaBytes(data);
            inst.UsedMemory_value(data);

            // If we have a number for physical memory use it to compute a percentage
            if (usermem > 0)
            {
                unsigned char percent = static_cast<unsigned char> (GetPercentage(0, data, 0, usermem));
                inst.PercentUsedMemory_value(percent);
            }
        }

        {
            data = 0;
            unsigned char percent = static_cast<unsigned char> (0);

            if (meminst->GetCacheSize(data) && usermem > 0)
            {
                percent = static_cast<unsigned char> (GetPercentage(0, BytesToMegaBytes(data), 0, usermem));
            }
            inst.PercentUsedByCache_value(percent);
        }

        bool pageReadsAvailable = meminst->GetPageReads(data);
        bool pageWritesAvailable = meminst->GetPageWrites(data2);
        if (pageReadsAvailable && pageWritesAvailable)
        {
            inst.PagesPerSec_value(data + data2);
        }

        if (pageReadsAvailable)
        {
            inst.PagesReadPerSec_value(data);
        }

        if (pageWritesAvailable)
        {
            inst.PagesWrittenPerSec_value(data2);
        }

        if (meminst->GetAvailableSwap(data))
        {
            // Adjust numbers from PAL to Megabytes
            data = BytesToMegaBytes(data);
            inst.AvailableSwap_value(data);

            if (meminst->GetTotalSwap(data2))
            {
                // Adjust numbers from PAL to Megabytes
                data2 = BytesToMegaBytes(data2);

                unsigned char percent = static_cast<unsigned char> (GetPercentage(0, data, 0, data2));
                inst.PercentAvailableSwap_value(percent);
            }
        }

        if (meminst->GetUsedSwap(data))
        {
            // Adjust numbers from PAL to Megabytes
            data = BytesToMegaBytes(data);

            inst.UsedSwap_value(data);

            if (meminst->GetTotalSwap(data2))
            {
                // Adjust numbers from PAL to Megabytes
                data2 = BytesToMegaBytes(data2);

                unsigned char percent = static_cast<unsigned char> (GetPercentage(0, data, 0, data2));
                inst.PercentUsedSwap_value(percent);
            }
        }
    }

    context.Post(inst);
}