Index: /trunk/src/VBox/Main/Performance.cpp
===================================================================
--- /trunk/src/VBox/Main/Performance.cpp	(revision 10724)
+++ /trunk/src/VBox/Main/Performance.cpp	(revision 10725)
@@ -483,6 +483,30 @@
     com::SafeIfaceArray <IUnknown> objectArray(ComSafeArrayInArg(objects));
     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]);
+    if (objectArray.isNull())
+    {
+        if (nameArray.size())
+        {
+            for (size_t i = 0; i < nameArray.size(); ++i)
+                processMetricList(std::string(com::Utf8Str(nameArray[i])), ComPtr<IUnknown>());
+        }
+        else
+            processMetricList(std::string("*"), ComPtr<IUnknown>());
+    }
+    else
+    {
+        for (size_t i = 0; i < objectArray.size(); ++i)
+            switch (nameArray.size())
+            {
+                case 0:
+                    processMetricList(std::string("*"), objectArray[i]);
+                    break;
+                case 1:
+                    processMetricList(std::string(com::Utf8Str(nameArray[0])), objectArray[i]);
+                    break;
+                default:
+                    processMetricList(std::string(com::Utf8Str(nameArray[i])), objectArray[i]);
+                    break;
+            }
+    }
 }
 
@@ -503,4 +527,21 @@
 bool Filter::match(const ComPtr<IUnknown> object, const std::string &name) const
 {
-    return true;
-}
+    ElementList::const_iterator it;
+
+    printf("Filter::match(%p, %s)\n", static_cast<const IUnknown*> (object), name.c_str());
+    for (it = mElements.begin(); it != mElements.end(); it++)
+    {
+        printf("...matching against(%p, %s)\n", static_cast<const IUnknown*> ((*it).first), (*it).second.c_str());
+        if ((*it).first.isNull() || (*it).first == object)
+        {
+            // Objects match, compare names
+            if ((*it).second == "*" || (*it).second == name)
+            {
+                printf("...found!\n");
+                return true;
+            }
+        }
+    }
+    printf("...no matches!\n");
+    return false;
+}
Index: /trunk/src/VBox/Main/PerformanceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 10724)
+++ /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 10725)
@@ -183,14 +183,36 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-STDMETHODIMP PerformanceCollector::GetMetrics(ComSafeArrayIn(const BSTR, metricNames),
+STDMETHODIMP PerformanceCollector::GetMetrics(ComSafeArrayIn(INPTR BSTR, metricNames),
                                               ComSafeArrayIn(IUnknown *, objects),
-                                              ComSafeArrayOut(IPerformanceMetric *, metrics))
+                                              ComSafeArrayOut(IPerformanceMetric *, outMetrics))
 {
     //LogFlowThisFunc (("mState=%d, mType=%d\n", mState, mType));
 
-    AutoCaller autoCaller (this);
-    CheckComRCReturnRC (autoCaller.rc());
-
-    return E_NOTIMPL;
+    HRESULT rc = S_OK;
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
+
+    MetricList filteredMetrics;
+    MetricList::iterator it;
+    for (it = m.mMetrics.begin(); it != m.mMetrics.end(); ++it)
+        if (filter.match((*it)->getObject(), (*it)->getName()))
+            filteredMetrics.push_back(*it);
+
+    com::SafeIfaceArray<IPerformanceMetric> retMetrics(filteredMetrics.size());
+    int i = 0;
+    for (it = m.mMetrics.begin(); it != m.mMetrics.end(); ++it)
+    {
+        ComObjPtr<PerformanceMetric> metric;
+        rc = metric.createObject();
+        if (SUCCEEDED (rc))
+            rc = metric->init (*it);
+        ComAssertComRCThrowRC (rc);
+        metric.queryInterfaceTo(&retMetrics[i++]);
+    }
+    retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
+    return rc;
 }
 
@@ -199,4 +221,7 @@
                                                  ULONG aPeriod, ULONG aCount)
 {
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
     pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
 
@@ -212,7 +237,10 @@
 }
 
-STDMETHODIMP PerformanceCollector::EnableMetrics (ComSafeArrayIn(const BSTR, metricNames),
+STDMETHODIMP PerformanceCollector::EnableMetrics (ComSafeArrayIn(INPTR BSTR, metricNames),
                                                   ComSafeArrayIn(IUnknown *, objects))
 {
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
     pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
 
@@ -225,7 +253,10 @@
 }
 
-STDMETHODIMP PerformanceCollector::DisableMetrics (ComSafeArrayIn(const BSTR, metricNames),
+STDMETHODIMP PerformanceCollector::DisableMetrics (ComSafeArrayIn(INPTR BSTR, metricNames),
                                                    ComSafeArrayIn(IUnknown *, objects))
 {
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
     pm::Filter filter(ComSafeArrayInArg(metricNames), ComSafeArrayInArg(objects));
 
@@ -238,5 +269,5 @@
 }
 
-STDMETHODIMP PerformanceCollector::QueryMetricsData (ComSafeArrayIn(const BSTR, metricNames),
+STDMETHODIMP PerformanceCollector::QueryMetricsData (ComSafeArrayIn(INPTR BSTR, metricNames),
                                                      ComSafeArrayIn(IUnknown *, objects),
                                                      ComSafeArrayOut(BSTR, outMetricNames),
@@ -398,5 +429,5 @@
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(Period) (unsigned long *aPeriod)
+STDMETHODIMP PerformanceMetric::COMGETTER(Period) (ULONG *aPeriod)
 {
     *aPeriod = mMetric->getPeriod();
@@ -404,5 +435,5 @@
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(Count) (unsigned long *aCount)
+STDMETHODIMP PerformanceMetric::COMGETTER(Count) (ULONG *aCount)
 {
     *aCount = mMetric->getLength();
@@ -417,5 +448,5 @@
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(MinValue) (long *aMinValue)
+STDMETHODIMP PerformanceMetric::COMGETTER(MinimumValue) (LONG *aMinValue)
 {
     *aMinValue = mMetric->getMinValue();
@@ -423,5 +454,5 @@
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(MaxValue) (long *aMaxValue)
+STDMETHODIMP PerformanceMetric::COMGETTER(MaximumValue) (LONG *aMaxValue)
 {
     *aMaxValue = mMetric->getMaxValue();
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 10724)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 10725)
@@ -10158,5 +10158,5 @@
     <desc>
       The IPerformanceCollector interface represents a service that collects and
-      stores performace metrics data.
+      stores performance metrics data.
 
       Performance metrics are associated with objects like IHost and IMachine.
Index: /trunk/src/VBox/Main/include/Performance.h
===================================================================
--- /trunk/src/VBox/Main/include/Performance.h	(revision 10724)
+++ /trunk/src/VBox/Main/include/Performance.h	(revision 10725)
@@ -326,5 +326,7 @@
     private:
         typedef std::pair<const ComPtr<IUnknown>, const std::string> FilterElement;
-        std::list<FilterElement> mElements;
+        typedef std::list<FilterElement> ElementList;
+
+        ElementList mElements;
 
         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 10724)
+++ /trunk/src/VBox/Main/include/PerformanceImpl.h	(revision 10725)
@@ -87,9 +87,9 @@
     STDMETHOD(COMGETTER(MetricName)) (BSTR *aMetricName);
     STDMETHOD(COMGETTER(Object)) (IUnknown **anObject);
-    STDMETHOD(COMGETTER(Period)) (unsigned long *aPeriod);
-    STDMETHOD(COMGETTER(Count)) (unsigned long *aCount);
+    STDMETHOD(COMGETTER(Period)) (ULONG *aPeriod);
+    STDMETHOD(COMGETTER(Count)) (ULONG *aCount);
     STDMETHOD(COMGETTER(Unit)) (BSTR *aUnit);
-    STDMETHOD(COMGETTER(MinValue)) (long *aMinValue);
-    STDMETHOD(COMGETTER(MaxValue)) (long *aMaxValue);
+    STDMETHOD(COMGETTER(MinimumValue)) (LONG *aMinValue);
+    STDMETHOD(COMGETTER(MaximumValue)) (LONG *aMaxValue);
 
     // IPerformanceMetric methods
@@ -202,15 +202,15 @@
 
     // IPerformanceCollector methods
-    STDMETHOD(GetMetrics) (ComSafeArrayIn (const BSTR, metricNames),
+    STDMETHOD(GetMetrics) (ComSafeArrayIn (INPTR BSTR, metricNames),
                            ComSafeArrayIn (IUnknown *, objects),
-                           ComSafeArrayOut (IPerformanceMetric *, metrics));
+                           ComSafeArrayOut (IPerformanceMetric *, outMetrics));
     STDMETHOD(SetupMetrics) (ComSafeArrayIn (INPTR BSTR, metricNames),
                              ComSafeArrayIn (IUnknown *, objects),
                              ULONG aPeriod, ULONG aCount);
-    STDMETHOD(EnableMetrics) (ComSafeArrayIn (const BSTR, metricNames),
+    STDMETHOD(EnableMetrics) (ComSafeArrayIn (INPTR BSTR, metricNames),
                               ComSafeArrayIn (IUnknown *, objects));
-    STDMETHOD(DisableMetrics) (ComSafeArrayIn (const BSTR, metricNames),
+    STDMETHOD(DisableMetrics) (ComSafeArrayIn (INPTR BSTR, metricNames),
                                ComSafeArrayIn (IUnknown *, objects));
-    STDMETHOD(QueryMetricsData) (ComSafeArrayIn (const BSTR, metricNames),
+    STDMETHOD(QueryMetricsData) (ComSafeArrayIn (INPTR BSTR, metricNames),
                                  ComSafeArrayIn (IUnknown *, objects),
                                  ComSafeArrayOut (BSTR, outMetricNames),
Index: /trunk/src/VBox/Main/testcase/tstAPI.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 10724)
+++ /trunk/src/VBox/Main/testcase/tstAPI.cpp	(revision 10725)
@@ -43,4 +43,11 @@
 
 #define printf RTPrintf
+
+
+// forward declarations
+///////////////////////////////////////////////////////////////////////////////
+
+void queryMetrics (ComPtr <IPerformanceCollector> collector,
+                   ComSafeArrayIn (IUnknown *, objects));
 
 // funcs
@@ -921,62 +928,33 @@
 #if 1
     do {
+        // Get collector
+        ComPtr <IPerformanceCollector> collector;
+        CHECK_ERROR_BREAK (virtualBox,
+                           COMGETTER(PerformanceCollector) (collector.asOutParam()));
+
+
+        // Fill base metrics array
         Bstr baseMetricNames[] = { L"CPU/Load,RAM/Usage" };
         com::SafeArray<BSTR> baseMetrics (1);
         baseMetricNames[0].cloneTo (&baseMetrics [0]);
 
+        // Get host
         ComPtr <IHost> host;
         CHECK_ERROR_BREAK (virtualBox, COMGETTER(Host) (host.asOutParam()));
-        ComPtr <IPerformanceCollector> collector;
-        CHECK_ERROR_BREAK (virtualBox,
-                           COMGETTER(PerformanceCollector) (collector.asOutParam()));
-
-        com::SafeIfaceArray<IUnknown> objects(1);
-        host.queryInterfaceTo(&objects[0]);
-        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;
-        com::SafeArray<ULONG>         retIndices;
-        com::SafeArray<ULONG>         retLengths;
-        com::SafeArray<LONG>          retData;
-        CHECK_ERROR_BREAK (collector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
-                                                       ComSafeArrayAsInParam(objects),
-                                                       ComSafeArrayAsOutParam(retNames),
-                                                       ComSafeArrayAsOutParam(retObjects),
-                                                       ComSafeArrayAsOutParam(retIndices),
-                                                       ComSafeArrayAsOutParam(retLengths),
-                                                       ComSafeArrayAsOutParam(retData)) );
-        for (unsigned i = 0; i < retNames.size(); i++)
-        {
-            Bstr metricName(retNames[i]);
-            printf("%ls", metricName.raw());
-            for (unsigned j = 0; j < retLengths[i]; j++)
-            {
-                printf(" %d", retData[retIndices[i] + j]);
-            }
-            printf("\n");
-        }
-    } while (0);
-#endif
-#if 0
-    for (int i = 0; i < 10; i++)
-    {
-        ULONG user, system, idle;
-        host->GetProcessorUsage(&user, &system, &idle);
-        printf("user=%u system=%u idle=%u\n", user/10000000, system/10000000, idle/10000000);
-    }
-#endif
-
-#if 0
-    {
+
+        // Get machine
         ComPtr <IMachine> machine;
         Bstr name = argc > 1 ? argv [1] : "dsl";
         printf ("Getting a machine object named '%ls'...\n", name.raw());
         CHECK_RC_BREAK (virtualBox->FindMachine (name, machine.asOutParam()));
+
+        // Setup base metrics
+        com::SafeIfaceArray<IUnknown> objects(2);
+        host.queryInterfaceTo(&objects[0]);
+        machine.queryInterfaceTo(&objects[1]);
+        CHECK_ERROR_BREAK (collector, SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
+                                                   ComSafeArrayAsInParam(objects), 1u, 10u) );
+
+        // Open session
         Guid guid;
         CHECK_RC_BREAK (machine->COMGETTER(Id) (guid.asOutParam()));
@@ -990,28 +968,26 @@
         printf ("Getting sessioned machine object...\n");
         CHECK_RC_BREAK (session->COMGETTER(Machine) (sessionMachine.asOutParam()));
+
+        // Get console
         ComPtr <IConsole> console;
         printf ("Getting console object...\n");
         CHECK_RC_BREAK (session->COMGETTER(Console) (console.asOutParam()));
-        for (int i = 0; i < 10; i++)
-        {
-            ComPtr <IHost> host;
-            CHECK_RC_BREAK (virtualBox->COMGETTER(Host) (host.asOutParam()));
-            ULONG user, system;
-            sessionMachine->GetProcessorUsage(&user, &system);
-            printf("VM: user=%u system=%u\n", user/10000000, system/10000000);
-            RTThreadSleep(1000);
-        }
+
+        RTThreadSleep(3000); // Sleep for 10 seconds
+
+        printf("Metrics collected with DSL machine running: --------------------\n");
+        queryMetrics(collector, ComSafeArrayAsInParam(objects));
+
+        // Pause
         printf ("Press enter to pause the VM execution in the remote session...");
         getchar();
         CHECK_RC (console->Pause());
-        for (int i = 0; i < 10; i++)
-        {
-            ComPtr <IHost> host;
-            CHECK_RC_BREAK (virtualBox->COMGETTER(Host) (host.asOutParam()));
-            ULONG user, system;
-            sessionMachine->GetProcessorUsage(&user, &system);
-            printf("VM: user=%u system=%u\n", user/10000000, system/10000000);
-            RTThreadSleep(1000);
-        }
+
+        RTThreadSleep(3000); // Sleep for 10 seconds
+
+        printf("Metrics collected with DSL machine paused: ---------------------\n");
+        queryMetrics(collector, ComSafeArrayAsInParam(objects));
+
+        // Power off
         printf ("Press enter to power off VM...");
         getchar();
@@ -1020,5 +996,5 @@
         getchar();
         session->Close();
-    }
+    } while (false);
 #endif
 
@@ -1040,2 +1016,46 @@
     return rc;
 }
+
+void queryMetrics (ComPtr <IPerformanceCollector> collector,
+                   ComSafeArrayIn (IUnknown *, objects))
+{
+    HRESULT rc;
+
+    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;
+    com::SafeArray<ULONG>         retIndices;
+    com::SafeArray<ULONG>         retLengths;
+    com::SafeArray<LONG>          retData;
+    CHECK_ERROR (collector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
+                                             ComSafeArrayInArg(objects),
+                                             ComSafeArrayAsOutParam(retNames),
+                                             ComSafeArrayAsOutParam(retObjects),
+                                             ComSafeArrayAsOutParam(retIndices),
+                                             ComSafeArrayAsOutParam(retLengths),
+                                             ComSafeArrayAsOutParam(retData)) );
+    for (unsigned i = 0; i < retNames.size(); i++)
+    {
+        // Get info for the metric
+        com::SafeArray<BSTR> nameOfMetric(1);
+        Bstr (retNames[i]).cloneTo (&nameOfMetric[0]);
+        com::SafeIfaceArray<IUnknown> anObject(1);
+        ComPtr<IUnknown>(retObjects[i]).queryInterfaceTo(&anObject[0]);
+        com::SafeIfaceArray <IPerformanceMetric> metricInfo;
+        CHECK_RC_BREAK (collector->GetMetrics( ComSafeArrayAsInParam(nameOfMetric),
+                                               ComSafeArrayAsInParam(anObject),
+                                               ComSafeArrayAsOutParam(metricInfo) ));
+        BSTR metricUnitBSTR;
+        CHECK_RC_BREAK (metricInfo[0]->COMGETTER(Unit) (&metricUnitBSTR));
+        Bstr metricUnit(metricUnitBSTR);
+        Bstr metricName(retNames[i]);
+        printf("%ls", metricName.raw());
+        for (unsigned j = 0; j < retLengths[i]; j++)
+        {
+            printf(", %d %s", retData[retIndices[i] + j], metricUnit.raw());
+        }
+        printf("\n");
+    }
+}
