Index: /trunk/src/VBox/Main/HostImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/HostImpl.cpp	(revision 10712)
+++ /trunk/src/VBox/Main/HostImpl.cpp	(revision 10713)
@@ -2696,7 +2696,10 @@
     pm::MetricFactory *metricFactory = aCollector->getMetricFactory();
     /* Create sub metrics */
-    pm::SubMetric *cpuLoadUser = new pm::SubMetric ("CPU/Load/User");
+    pm::SubMetric *cpuLoadUser   = new pm::SubMetric ("CPU/Load/User");
     pm::SubMetric *cpuLoadKernel = new pm::SubMetric ("CPU/Load/Kernel");
-    pm::SubMetric *cpuLoadIdle = new pm::SubMetric ("CPU/Load/Idle");
+    pm::SubMetric *cpuLoadIdle   = new pm::SubMetric ("CPU/Load/Idle");
+    pm::SubMetric *ramUsageTotal = new pm::SubMetric ("RAM/Usage/Total");
+    pm::SubMetric *ramUsageUsed  = new pm::SubMetric ("RAM/Usage/Used");
+    pm::SubMetric *ramUsageFree  = new pm::SubMetric ("RAM/Usage/Free");
     /* Create and register base metrics */
     IUnknown *objptr;
@@ -2707,4 +2710,9 @@
                                           cpuLoadIdle);
     aCollector->registerBaseMetric (cpuLoad);
+    pm::BaseMetric *ramUsage =
+        metricFactory->createHostCpuLoad (objptr, ramUsageTotal, ramUsageUsed,
+                                          ramUsageFree);
+    aCollector->registerBaseMetric (ramUsage);
+
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadUser, 0));
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadUser,
@@ -2714,4 +2722,5 @@
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadUser,
                                                new pm::AggregateMax()));
+
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadKernel, 0));
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadKernel,
@@ -2721,4 +2730,5 @@
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadKernel,
                                                new pm::AggregateMax()));
+
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadIdle, 0));
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadIdle,
@@ -2728,4 +2738,28 @@
     aCollector->registerMetric (new pm::Metric(cpuLoad, cpuLoadIdle,
                                                new pm::AggregateMax()));
+
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageTotal, 0));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageTotal,
+                                               new pm::AggregateAvg()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageTotal,
+                                               new pm::AggregateMin()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageTotal,
+                                               new pm::AggregateMax()));
+
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageUsed, 0));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageUsed,
+                                               new pm::AggregateAvg()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageUsed,
+                                               new pm::AggregateMin()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageUsed,
+                                               new pm::AggregateMax()));
+
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageFree, 0));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageFree,
+                                               new pm::AggregateAvg()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageFree,
+                                               new pm::AggregateMin()));
+    aCollector->registerMetric (new pm::Metric(ramUsage, ramUsageFree,
+                                               new pm::AggregateMax()));
 };
 
Index: /trunk/src/VBox/Main/Performance.cpp
===================================================================
--- /trunk/src/VBox/Main/Performance.cpp	(revision 10712)
+++ /trunk/src/VBox/Main/Performance.cpp	(revision 10713)
@@ -35,25 +35,25 @@
 // Default factory
 
-BaseMetric *MetricFactory::createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+BaseMetric *MetricFactory::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
 {
     Assert(mHAL);
     return new HostCpuLoad(mHAL, object, user, kernel, idle);
 }
-BaseMetric *MetricFactory::createHostCpuMHz(IUnknown *object, SubMetric *mhz)
+BaseMetric *MetricFactory::createHostCpuMHz(ComPtr<IUnknown> object, SubMetric *mhz)
 {
     Assert(mHAL);
     return new HostCpuMhz(mHAL, object, mhz);
 }
-BaseMetric *MetricFactory::createHostRamUsage(IUnknown *object, SubMetric *total, SubMetric *used, SubMetric *available)
+BaseMetric *MetricFactory::createHostRamUsage(ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
 {
     Assert(mHAL);
     return new HostRamUsage(mHAL, object, total, used, available);
 }
-BaseMetric *MetricFactory::createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+BaseMetric *MetricFactory::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
 {
     Assert(mHAL);
     return new MachineCpuLoad(mHAL, object, process, user, kernel);
 }
-BaseMetric *MetricFactory::createMachineRamUsage(IUnknown *object, RTPROCESS process, SubMetric *used)
+BaseMetric *MetricFactory::createMachineRamUsage(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
 {
     Assert(mHAL);
@@ -69,5 +69,5 @@
 }
 
-BaseMetric *MetricFactoryLinux::createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+BaseMetric *MetricFactoryLinux::createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
 {
     Assert(mHAL);
@@ -75,5 +75,5 @@
 }
 
-BaseMetric *MetricFactoryLinux::createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+BaseMetric *MetricFactoryLinux::createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
 {
     Assert(mHAL);
@@ -173,11 +173,47 @@
     return E_NOTIMPL;
 }
+
 int CollectorLinux::getHostMemoryUsage(unsigned long *total, unsigned long *used, unsigned long *available)
 {
-    return E_NOTIMPL;
+#ifdef RT_OS_LINUX
+    int rc = VINF_SUCCESS;
+    unsigned long buffers, cached;
+    FILE *f = fopen("/proc/meminfo", "r");
+
+    if (f)
+    {
+        int processed = fscanf(f, "MemTotal: %lu kB", total);
+        processed    += fscanf(f, "MemFree: %lu kB", available);
+        processed    += fscanf(f, "Buffers: %lu kB", &buffers);
+        processed    += fscanf(f, "Cached: %lu kB", &cached);
+        if (processed == 4)
+            *available += buffers + cached;
+        else
+            rc = VERR_FILE_IO_ERROR;
+        fclose(f);
+    }
+    else
+        rc = VERR_ACCESS_DENIED;
+
+    return rc;
+#else
+    return E_NOTIMPL;
+#endif
 }
 int CollectorLinux::getProcessMemoryUsage(RTPROCESS process, unsigned long *used)
 {
     return E_NOTIMPL;
+}
+
+void BaseMetric::collectorBeat(uint64_t nowAt)
+{
+    if (isEnabled())
+    {
+        if (nowAt - mLastSampleTaken >= mPeriod * 1000)
+        {
+            mLastSampleTaken = nowAt;
+            collect();
+        }
+    }
 }
 
@@ -205,18 +241,21 @@
     unsigned long userDiff, kernelDiff, idleDiff, totalDiff;
 
-    mHAL->getRawHostCpuLoad(&user, &kernel, &idle);
-
-    userDiff   = user   - mUserPrev;
-    kernelDiff = kernel - mKernelPrev;
-    idleDiff   = idle   - mIdlePrev;
-    totalDiff  = userDiff + kernelDiff + idleDiff;
-
-    mUser->put(PM_CPU_LOAD_MULTIPLIER * userDiff / totalDiff);
-    mKernel->put(PM_CPU_LOAD_MULTIPLIER * kernelDiff / totalDiff);
-    mIdle->put(PM_CPU_LOAD_MULTIPLIER * idleDiff / totalDiff);
-
-    mUserPrev   = user;
-    mKernelPrev = kernel;
-    mIdlePrev   = idle;
+    int rc = mHAL->getRawHostCpuLoad(&user, &kernel, &idle);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        userDiff   = user   - mUserPrev;
+        kernelDiff = kernel - mKernelPrev;
+        idleDiff   = idle   - mIdlePrev;
+        totalDiff  = userDiff + kernelDiff + idleDiff;
+    
+        mUser->put(PM_CPU_LOAD_MULTIPLIER * userDiff / totalDiff);
+        mKernel->put(PM_CPU_LOAD_MULTIPLIER * kernelDiff / totalDiff);
+        mIdle->put(PM_CPU_LOAD_MULTIPLIER * idleDiff / totalDiff);
+    
+        mUserPrev   = user;
+        mKernelPrev = kernel;
+        mIdlePrev   = idle;
+    }
 }
 
@@ -231,6 +270,8 @@
 {
     unsigned long mhz;
-    mHAL->getHostCpuMHz(&mhz);
-    mMHz->put(mhz);
+    int rc = mHAL->getHostCpuMHz(&mhz);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+        mMHz->put(mhz);
 }
 
@@ -247,8 +288,12 @@
 {
     unsigned long total, used, available;
-    mHAL->getHostMemoryUsage(&total, &used, &available);
-    mTotal->put(total);
-    mUsed->put(used);
-    mAvailable->put(available);
+    int rc = mHAL->getHostMemoryUsage(&total, &used, &available);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        mTotal->put(total);
+        mUsed->put(used);
+        mAvailable->put(available);
+    }
 }
 
@@ -266,7 +311,11 @@
 {
     unsigned long user, kernel;
-    mHAL->getProcessCpuLoad(mProcess, &user, &kernel);
-    mUser->put(user);
-    mKernel->put(kernel);
+    int rc = mHAL->getProcessCpuLoad(mProcess, &user, &kernel);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        mUser->put(user);
+        mKernel->put(kernel);
+    }
 }
 
@@ -276,14 +325,22 @@
     unsigned long processUser, processKernel;
 
-    mHAL->getRawHostCpuLoad(&hostUser, &hostKernel, &hostIdle);
-    hostTotal = hostUser + hostKernel + hostIdle;
-
-    mHAL->getRawProcessCpuLoad(mProcess, &processUser, &processKernel);
-    mUser->put(PM_CPU_LOAD_MULTIPLIER * (processUser - mProcessUserPrev) / (hostTotal - mHostTotalPrev));
-    mUser->put(PM_CPU_LOAD_MULTIPLIER * (processKernel - mProcessKernelPrev ) / (hostTotal - mHostTotalPrev));
-
-    mHostTotalPrev     = hostTotal;
-    mProcessUserPrev   = processUser;
-    mProcessKernelPrev = processKernel;
+    int rc = mHAL->getRawHostCpuLoad(&hostUser, &hostKernel, &hostIdle);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+    {
+        hostTotal = hostUser + hostKernel + hostIdle;
+    
+        rc = mHAL->getRawProcessCpuLoad(mProcess, &processUser, &processKernel);
+        AssertRC(rc);
+        if (RT_SUCCESS(rc))
+        {
+            mUser->put(PM_CPU_LOAD_MULTIPLIER * (processUser - mProcessUserPrev) / (hostTotal - mHostTotalPrev));
+            mUser->put(PM_CPU_LOAD_MULTIPLIER * (processKernel - mProcessKernelPrev ) / (hostTotal - mHostTotalPrev));
+        
+            mHostTotalPrev     = hostTotal;
+            mProcessUserPrev   = processUser;
+            mProcessKernelPrev = processKernel;
+        }
+    }
 }
 
@@ -298,6 +355,8 @@
 {
     unsigned long used;
-    mHAL->getProcessMemoryUsage(mProcess, &used);
-    mUsed->put(used);
+    int rc = mHAL->getProcessMemoryUsage(mProcess, &used);
+    AssertRC(rc);
+    if (RT_SUCCESS(rc))
+        mUsed->put(used);
 }
 
@@ -308,30 +367,42 @@
     mLength = length;
     mData = (unsigned long *)RTMemAllocZ(length * sizeof(unsigned long));
-    mPosition = 0;
+    mWrapped = false;
+    mEnd = 0;
 }
 
 unsigned long CircularBuffer::length()
 {
-    return mLength;
+    return mWrapped ? mLength : mEnd;
 }
 
 void CircularBuffer::put(unsigned long value)
 {
-    mData[mPosition++] = value;
-    if (mPosition >= mLength)
-        mPosition = 0;
-}
-
-void CircularBuffer::copyTo(unsigned long *data, unsigned long length)
-{
-    memcpy(data, mData + mPosition, (length - mPosition) * sizeof(unsigned long));
-    // Copy the wrapped part
-    if (mPosition)
-        memcpy(data + mPosition, mData, mPosition * sizeof(unsigned long));
-}
-
-void SubMetric::query(unsigned long *data, unsigned long count)
-{
-    copyTo(data, count);
+    if (mData)
+    {
+        mData[mEnd++] = value;
+        if (mEnd >= mLength)
+        {
+            mEnd = 0;
+            mWrapped = true;
+        }
+    }
+}
+
+void CircularBuffer::copyTo(unsigned long *data)
+{
+    if (mWrapped)
+    {
+        memcpy(data, mData + mEnd, (mLength - mEnd) * sizeof(unsigned long));
+        // Copy the wrapped part
+        if (mEnd)
+            memcpy(data + mEnd, mData, mEnd * sizeof(unsigned long));
+    }
+    else
+        memcpy(data, mData, mEnd * sizeof(unsigned long));
+}
+
+void SubMetric::query(unsigned long *data)
+{
+    copyTo(data);
 }
     
@@ -345,5 +416,5 @@
     {
         tmpData = (unsigned long*)RTMemAlloc(sizeof(*tmpData)*length);
-        mSubMetric->query(tmpData, length);
+        mSubMetric->query(tmpData);
         if (mAggregate)
         {
@@ -351,4 +422,5 @@
             *data  = (unsigned long*)RTMemAlloc(sizeof(**data));
             **data = mAggregate->compute(tmpData, length);
+            RTMemFree(tmpData);
         }
         else
@@ -367,5 +439,8 @@
 unsigned long AggregateAvg::compute(unsigned long *data, unsigned long length)
 {
-    return 0;
+    uint64_t tmp = 0;
+    for (unsigned long i = 0; i < length; ++i)
+        tmp += data[i];
+    return tmp / length;
 }
 
@@ -377,5 +452,9 @@
 unsigned long AggregateMin::compute(unsigned long *data, unsigned long length)
 {
-    return 0;
+    unsigned long tmp = *data;
+    for (unsigned long i = 0; i < length; ++i)
+        if (data[i] < tmp)
+            tmp = data[i];
+    return tmp;
 }
 
@@ -387,5 +466,9 @@
 unsigned long AggregateMax::compute(unsigned long *data, unsigned long length)
 {
-    return 0;
+    unsigned long tmp = *data;
+    for (unsigned long i = 0; i < length; ++i)
+        if (data[i] > tmp)
+            tmp = data[i];
+    return tmp;
 }
 
@@ -395,14 +478,14 @@
 }
 
-Filter::Filter(ComSafeArrayIn(const BSTR, metricNames),
+Filter::Filter(ComSafeArrayIn(INPTR BSTR, metricNames),
                ComSafeArrayIn(IUnknown *, objects))
 {
     com::SafeIfaceArray <IUnknown> objectArray(ComSafeArrayInArg(objects));
-    com::SafeArray <BSTR> nameArray(ComSafeArrayInArg(metricNames));
+    com::SafeArray <INPTR BSTR> nameArray(ComSafeArrayInArg(metricNames));
     for (size_t i = 0; i < objectArray.size(); ++i)
         processMetricList(std::string(com::Utf8Str(nameArray[i])), objectArray[i]);
 }
 
-void Filter::processMetricList(const std::string &name, const IUnknown *object)
+void Filter::processMetricList(const std::string &name, const ComPtr<IUnknown> object)
 {
     std::string::size_type startPos = 0;
@@ -418,5 +501,5 @@
 }
 
-bool Filter::match(const IUnknown *object, const std::string &name) const
+bool Filter::match(const ComPtr<IUnknown> object, const std::string &name) const
 {
     return true;
Index: /trunk/src/VBox/Main/PerformanceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 10712)
+++ /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 10713)
@@ -69,5 +69,5 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-PerformanceCollector::PerformanceCollector() {}
+PerformanceCollector::PerformanceCollector() : mMagic(0) {}
 
 PerformanceCollector::~PerformanceCollector() {}
@@ -103,6 +103,9 @@
     /* @todo Obviously other platforms must be added as well. */
     m.mFactory = new pm::MetricFactoryLinux();
+
+    /* Let the sampler know it gets a valid collector.  */
+    mMagic = MAGIC;
+
     /* Start resource usage sampler */
-
     int vrc = RTTimerCreate (&m.mSampler, VBOX_USAGE_SAMPLER_MIN_INTERVAL,
                              &PerformanceCollector::staticSamplerCallback, this);
@@ -138,4 +141,6 @@
     }
 
+    mMagic = 0;
+
     /* Destroy resource usage sampler */
     int vrc = RTTimerDestroy (m.mSampler);
@@ -190,5 +195,5 @@
 }
 
-STDMETHODIMP PerformanceCollector::SetupMetrics (ComSafeArrayIn(const BSTR, metricNames),
+STDMETHODIMP PerformanceCollector::SetupMetrics (ComSafeArrayIn(INPTR BSTR, metricNames),
                                                  ComSafeArrayIn(IUnknown *, objects),
                                                  ULONG aPeriod, ULONG aCount)
@@ -199,5 +204,8 @@
     for (it = m.mBaseMetrics.begin(); it != m.mBaseMetrics.end(); ++it)
         if (filter.match((*it)->getObject(), (*it)->getName()))
+        {
             (*it)->init(aPeriod, aCount);
+            (*it)->enable();
+        }
 
     return S_OK;
@@ -207,5 +215,12 @@
                                                   ComSafeArrayIn(IUnknown *, objects))
 {
-    return E_NOTIMPL;
+    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
+
+    BaseMetricList::iterator it;
+    for (it = m.mBaseMetrics.begin(); it != m.mBaseMetrics.end(); ++it)
+        if (filter.match((*it)->getObject(), (*it)->getName()))
+            (*it)->enable();
+
+    return S_OK;
 }
 
@@ -213,5 +228,12 @@
                                                    ComSafeArrayIn(IUnknown *, objects))
 {
-    return E_NOTIMPL;
+    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
+
+    BaseMetricList::iterator it;
+    for (it = m.mBaseMetrics.begin(); it != m.mBaseMetrics.end(); ++it)
+        if (filter.match((*it)->getObject(), (*it)->getName()))
+            (*it)->disable();
+
+    return S_OK;
 }
 
@@ -245,4 +267,5 @@
     com::SafeArray<ULONG> retLengths(numberOfMetrics);
     com::SafeArray<LONG> retData(flatSize);
+
     for (it = m.mMetrics.begin(), i = 0; it != m.mMetrics.end(); ++it)
     {
@@ -254,5 +277,5 @@
         Bstr tmp((*it)->getName());
         tmp.detachTo(&retNames[i]);
-        retObjects[i] = (*it)->getObject();
+        (*it)->getObject().queryInterfaceTo(&retObjects[i]);
         retLengths[i] = length;
         retIndices[i] = flatIndex;
@@ -260,4 +283,5 @@
         flatIndex += length;
     }
+
     retNames.detachTo(ComSafeArrayOutArg(outMetricNames));
     retObjects.detachTo(ComSafeArrayOutArg(outObjects));
@@ -303,9 +327,17 @@
 {
     AssertReturnVoid (pvUser != NULL);
-    static_cast <PerformanceCollector *> (pvUser)->samplerCallback();
+    PerformanceCollector *collector = static_cast <PerformanceCollector *> (pvUser);
+    Assert(collector->mMagic == MAGIC);
+    if (collector->mMagic == MAGIC)
+    {
+        collector->samplerCallback();
+    }
 }
 
 void PerformanceCollector::samplerCallback()
 {
+    uint64_t timestamp = RTTimeMilliTS();
+    std::for_each(m.mBaseMetrics.begin(), m.mBaseMetrics.end(),
+                  std::bind2nd (std::mem_fun (&pm::BaseMetric::collectorBeat), timestamp));
 }
 
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 10712)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 10713)
@@ -10157,6 +10157,6 @@
   >
     <desc>
-      The IPerformanceCollector interfaces represents a service that collects
-      and stores performace metrics data.
+      The IPerformanceCollector interface represents a service that collects and
+      stores performace metrics data.
 
       Performance metrics are associated with objects like IHost and IMachine.
@@ -10280,8 +10280,15 @@
       <desc>
         Queries collected metrics data for a set of objects.
+        
+        The data itself and related metric information are returned in four
+        parallel and one flattened array of arrays. Elements of @c
+        returnMetricNames, @c returnObjects, @c returnDataIndices and @ 
+        returnDataLengths with the same index describe one set of values 
+        corresponding to a single metric.
 
         The @a returnData parameter is a flattened array of arrays. Each start
         and length of a sub-array is indicated by @a returnDataIndices and @a
-        returnDataLengths.
+        returnDataLengths. The first value for metric <tt>metricNames[i]</tt> is at
+        <tt> returnData[returnIndices[i]]</tt>.
 
         <note>
@@ -10325,6 +10332,5 @@
         <desc>
           Flattened array of all metric data containing sequences of values for 
-          each metric. The first value for metric <tt>metricNames[i]</tt> is at
-          <tt> returnData[returnIndices[i]]</tt>.
+          each metric.
         </desc>
       </param>
Index: /trunk/src/VBox/Main/include/Performance.h
===================================================================
--- /trunk/src/VBox/Main/include/Performance.h	(revision 10712)
+++ /trunk/src/VBox/Main/include/Performance.h	(revision 10713)
@@ -29,12 +29,5 @@
 
 namespace pm {
-    const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(1000000000);
-    /*IUnknown * iunknown(ComPtr<IUnknown> object)
-    {
-        IUnknown *objptr;
-
-        object.queryInterfaceTo(&objptr);
-        return objptr;
-    }*/
+    const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000000);
 
     /* Sub Metrics **********************************************************/
@@ -42,13 +35,14 @@
     {
     public:
-        CircularBuffer() : mData(0), mLength(0), mPosition(0) {};
+        CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
         void init(unsigned long length);
         unsigned long length();
         void put(unsigned long value);
-        void copyTo(unsigned long *data, unsigned long length);
+        void copyTo(unsigned long *data);
     private:
         unsigned long *mData;
-        unsigned long mLength;
-        unsigned long mPosition;
+        unsigned long  mLength;
+        unsigned long  mEnd;
+        bool           mWrapped;
     };
 
@@ -58,5 +52,5 @@
         SubMetric(const char *name)
         : mName(name) {};
-        void query(unsigned long *data, unsigned long count);
+        void query(unsigned long *data);
         const char *getName() { return mName; };
     private:
@@ -94,6 +88,6 @@
     {
     public:
-        BaseMetric(CollectorHAL *hal, const char *name, IUnknown *object)
-            : mHAL(hal), mLength(0), mName(name), mObject(object) {};
+        BaseMetric(CollectorHAL *hal, const char *name, ComPtr<IUnknown> object)
+            : mHAL(hal), mLength(0), mName(name), mObject(object), mLastSampleTaken(0), mEnabled(false) {};
 
         virtual void init(unsigned long period, unsigned long length) = 0;
@@ -103,16 +97,24 @@
         virtual unsigned long getMaxValue() = 0;
 
+        void collectorBeat(uint64_t nowAt);
+
+        void enable() { mEnabled = true; };
+        void disable() { mEnabled = false; };
+
+        bool isEnabled() { return mEnabled; };
         unsigned long getPeriod() { return mPeriod; };
         unsigned long getLength() { return mLength; };
         const char *getName() { return mName; };
-        IUnknown *getObject() { return mObject; };
-        bool associatedWith(IUnknown *object) { return mObject == object; };
+        ComPtr<IUnknown> getObject() { return mObject; };
+        bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
 
     protected:
-        CollectorHAL *mHAL;
-        unsigned long mPeriod;
-        unsigned long mLength;
-        const char   *mName;
-        IUnknown     *mObject;
+        CollectorHAL    *mHAL;
+        unsigned long    mPeriod;
+        unsigned long    mLength;
+        const char      *mName;
+        ComPtr<IUnknown> mObject;
+        uint64_t         mLastSampleTaken;
+        bool             mEnabled;
     };
     
@@ -120,5 +122,5 @@
     {
     public:
-        HostCpuLoad(CollectorHAL *hal, IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+        HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
         : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
         void init(unsigned long period, unsigned long length);
@@ -138,5 +140,5 @@
     {
     public:
-        HostCpuLoadRaw(CollectorHAL *hal, IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
+        HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
         : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
 
@@ -151,5 +153,5 @@
     {
     public:
-        HostCpuMhz(CollectorHAL *hal, IUnknown *object, SubMetric *mhz)
+        HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
         : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
 
@@ -166,5 +168,5 @@
     {
     public:
-        HostRamUsage(CollectorHAL *hal, IUnknown *object, SubMetric *total, SubMetric *used, SubMetric *available)
+        HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
         : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
 
@@ -183,5 +185,5 @@
     {
     public:
-        MachineCpuLoad(CollectorHAL *hal, IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+        MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
         : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
 
@@ -200,5 +202,5 @@
     {
     public:
-        MachineCpuLoadRaw(CollectorHAL *hal, IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
+        MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
         : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
 
@@ -213,5 +215,5 @@
     {
     public:
-        MachineRamUsage(CollectorHAL *hal, IUnknown *object, RTPROCESS process, SubMetric *used)
+        MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
         : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
 
@@ -273,8 +275,8 @@
             delete mAggregate;
         }
-        bool associatedWith(IUnknown *object) { return getObject() == object; };
+        bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
 
         const char *getName() { return mName.c_str(); };
-        IUnknown *getObject() { return mBaseMetric->getObject(); };
+        ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
         const char *getUnit() { return mBaseMetric->getUnit(); };
         unsigned long getMinValue() { return mBaseMetric->getMinValue(); };
@@ -298,9 +300,9 @@
         ~MetricFactory() { delete mHAL; };
 
-        virtual BaseMetric   *createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle);
-        virtual BaseMetric   *createHostCpuMHz(IUnknown *object, SubMetric *mhz);
-        virtual BaseMetric   *createHostRamUsage(IUnknown *object, SubMetric *total, SubMetric *used, SubMetric *available);
-        virtual BaseMetric   *createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel);
-        virtual BaseMetric   *createMachineRamUsage(IUnknown *object, RTPROCESS process, SubMetric *used);
+        virtual BaseMetric   *createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle);
+        virtual BaseMetric   *createHostCpuMHz(ComPtr<IUnknown> object, SubMetric *mhz);
+        virtual BaseMetric   *createHostRamUsage(ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available);
+        virtual BaseMetric   *createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel);
+        virtual BaseMetric   *createMachineRamUsage(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used);
     protected:
         CollectorHAL *mHAL;
@@ -312,6 +314,6 @@
     public:
         MetricFactoryLinux();
-        virtual BaseMetric   *createHostCpuLoad(IUnknown *object, SubMetric *user, SubMetric *kernel, SubMetric *idle);
-        virtual BaseMetric   *createMachineCpuLoad(IUnknown *object, RTPROCESS process, SubMetric *user, SubMetric *kernel);
+        virtual BaseMetric   *createHostCpuLoad(ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle);
+        virtual BaseMetric   *createMachineCpuLoad(ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel);
     };
 
@@ -319,12 +321,12 @@
     {
     public:
-        Filter(ComSafeArrayIn(const BSTR, metricNames),
-               ComSafeArrayIn(IUnknown *, objects));
-        bool match(const IUnknown *object, const std::string &name) const;
-    private:
-        typedef std::pair<const IUnknown*, const std::string> FilterElement;
+        Filter(ComSafeArrayIn(INPTR BSTR, metricNames),
+               ComSafeArrayIn(IUnknown * , objects));
+        bool match(const ComPtr<IUnknown> object, const std::string &name) const;
+    private:
+        typedef std::pair<const ComPtr<IUnknown>, const std::string> FilterElement;
         std::list<FilterElement> mElements;
 
-        void processMetricList(const std::string &name, const IUnknown *object);
+        void processMetricList(const std::string &name, const ComPtr<IUnknown> object);
     };
 }
Index: /trunk/src/VBox/Main/include/PerformanceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/PerformanceImpl.h	(revision 10712)
+++ /trunk/src/VBox/Main/include/PerformanceImpl.h	(revision 10713)
@@ -205,5 +205,5 @@
                            ComSafeArrayIn (IUnknown *, objects),
                            ComSafeArrayOut (IPerformanceMetric *, metrics));
-    STDMETHOD(SetupMetrics) (ComSafeArrayIn (const BSTR, metricNames),
+    STDMETHOD(SetupMetrics) (ComSafeArrayIn (INPTR BSTR, metricNames),
                              ComSafeArrayIn (IUnknown *, objects),
                              ULONG aPeriod, ULONG aCount);
@@ -243,4 +243,11 @@
     typedef std::list<pm::BaseMetric*> BaseMetricList;
 
+    enum
+    {
+        MAGIC = 0xABBA1972u
+    };
+
+    unsigned int mMagic;
+
     struct Data {
         Data() : mFactory(0) {};
Index: /trunk/src/VBox/Main/testcase/tstAPI.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 10712)
+++ /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 10713)
@@ -921,7 +921,7 @@
 #if 1
     do {
-        Bstr metricNames[] = { L"CPU/Load/User:avg,CPU/Load/System:avg,CPU/Load/Idle:avg" };
-        com::SafeArray<BSTR> metrics (1);
-        metricNames[0].cloneTo (&metrics [0]);
+        Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
+        com::SafeArray<BSTR> baseMetrics (1);
+        baseMetricNames[0].cloneTo (&baseMetrics [0]);
 
         ComPtr <IHost> host;
@@ -933,7 +933,11 @@
         com::SafeIfaceArray<IUnknown> objects(1);
         host.queryInterfaceTo(&objects[0]);
-        CHECK_ERROR_BREAK (collector, SetupMetrics(ComSafeArrayAsInParam(metrics),
+        CHECK_ERROR_BREAK (collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
                                                 ComSafeArrayAsInParam(objects), 1u, 10u) );
         RTThreadSleep(3000); /* Sleep 10 seconds. */
+
+        Bstr metricNames[] = { L"CPU/Load/User:avg,CPU/Load/System:avg,CPU/Load/Idle:avg,RAM/Usage/Total.RAM/Usage/Used:avg" };
+        com::SafeArray<BSTR> metrics (1);
+        metricNames[0].cloneTo (&metrics [0]);
         com::SafeArray<BSTR>          retNames;
         com::SafeIfaceArray<IUnknown> retObjects;
