Index: /trunk/src/VBox/Main/include/Performance.h
===================================================================
--- /trunk/src/VBox/Main/include/Performance.h	(revision 56586)
+++ /trunk/src/VBox/Main/include/Performance.h	(revision 56587)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2008-2013 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -882,14 +882,11 @@
     {
     public:
-        Filter(ComSafeArrayIn(IN_BSTR, metricNames),
-               ComSafeArrayIn(IUnknown * , objects));
-        Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
+        Filter(const std::vector<com::Utf8Str> &metricNames,
+               const std::vector<ComPtr<IUnknown> > &objects);
+        Filter(const com::Utf8Str &name, const ComPtr<IUnknown> &aObject);
         static bool patternMatch(const char *pszPat, const char *pszName,
                                  bool fSeenColon = false);
         bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
     private:
-        void init(ComSafeArrayIn(IN_BSTR, metricNames),
-                  ComSafeArrayIn(IUnknown * , objects));
-
         typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
         typedef std::list<FilterElement> ElementList;
Index: /trunk/src/VBox/Main/include/PerformanceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/PerformanceImpl.h	(revision 56586)
+++ /trunk/src/VBox/Main/include/PerformanceImpl.h	(revision 56587)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2008-2012 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -21,5 +21,6 @@
 #define ____H_PERFORMANCEIMPL
 
-#include "VirtualBoxBase.h"
+#include "PerformanceCollectorWrap.h"
+#include "PerformanceMetricWrap.h"
 
 #include <VBox/com/com.h>
@@ -46,22 +47,10 @@
 #define VBOX_USAGE_SAMPLER_MIN_INTERVAL 1000
 
-class HostUSBDevice;
-
 class ATL_NO_VTABLE PerformanceMetric :
-    public VirtualBoxBase,
-    VBOX_SCRIPTABLE_IMPL(IPerformanceMetric)
+    public PerformanceMetricWrap
 {
 public:
-    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(PerformanceMetric, IPerformanceMetric)
 
-    DECLARE_NOT_AGGREGATABLE (PerformanceMetric)
-
-    DECLARE_PROTECT_FINAL_CONSTRUCT()
-
-    BEGIN_COM_MAP (PerformanceMetric)
-        VBOX_DEFAULT_INTERFACE_ENTRIES (IPerformanceMetric)
-    END_COM_MAP()
-
-    DECLARE_EMPTY_CTOR_DTOR (PerformanceMetric)
+    DECLARE_EMPTY_CTOR_DTOR(PerformanceMetric)
 
     HRESULT FinalConstruct();
@@ -69,26 +58,19 @@
 
     // public initializer/uninitializer for internal purposes only
-    HRESULT init (pm::Metric *aMetric);
-    HRESULT init (pm::BaseMetric *aMetric);
+    HRESULT init(pm::Metric *aMetric);
+    HRESULT init(pm::BaseMetric *aMetric);
     void uninit();
 
-    // IPerformanceMetric properties
-    STDMETHOD(COMGETTER(MetricName)) (BSTR *aMetricName);
-    STDMETHOD(COMGETTER(Object)) (IUnknown **anObject);
-    STDMETHOD(COMGETTER(Description)) (BSTR *aDescription);
-    STDMETHOD(COMGETTER(Period)) (ULONG *aPeriod);
-    STDMETHOD(COMGETTER(Count)) (ULONG *aCount);
-    STDMETHOD(COMGETTER(Unit)) (BSTR *aUnit);
-    STDMETHOD(COMGETTER(MinimumValue)) (LONG *aMinValue);
-    STDMETHOD(COMGETTER(MaximumValue)) (LONG *aMaxValue);
+private:
 
-    // IPerformanceMetric methods
-
-    // public methods only for internal purposes
-
-    // public methods for internal purposes only
-    // (ensure there is a caller and a read lock before calling them!)
-
-private:
+    // wrapped IPerformanceMetric properties
+    HRESULT getMetricName(com::Utf8Str &aMetricName);
+    HRESULT getObject(ComPtr<IUnknown> &aObject);
+    HRESULT getDescription(com::Utf8Str &aDescription);
+    HRESULT getPeriod(ULONG *aPeriod);
+    HRESULT getCount(ULONG *aCount);
+    HRESULT getUnit(com::Utf8Str &aUnit);
+    HRESULT getMinimumValue(LONG *aMinimumValue);
+    HRESULT getMaximumValue(LONG *aMaximumValue);
 
     struct Data
@@ -100,10 +82,10 @@
         }
 
-        Bstr             name;
+        Utf8Str          name;
         ComPtr<IUnknown> object;
-        Bstr             description;
+        Utf8Str          description;
         ULONG            period;
         ULONG            count;
-        Bstr             unit;
+        Utf8Str          unit;
         LONG             min;
         LONG             max;
@@ -115,20 +97,9 @@
 
 class ATL_NO_VTABLE PerformanceCollector :
-    public VirtualBoxBase,
-    VBOX_SCRIPTABLE_IMPL(IPerformanceCollector)
+    public PerformanceCollectorWrap
 {
 public:
 
-    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(PerformanceCollector, IPerformanceCollector)
-
-    DECLARE_NOT_AGGREGATABLE (PerformanceCollector)
-
-    DECLARE_PROTECT_FINAL_CONSTRUCT()
-
-    BEGIN_COM_MAP(PerformanceCollector)
-        VBOX_DEFAULT_INTERFACE_ENTRIES(IPerformanceCollector)
-    END_COM_MAP()
-
-    DECLARE_EMPTY_CTOR_DTOR (PerformanceCollector)
+    DECLARE_EMPTY_CTOR_DTOR(PerformanceCollector)
 
     HRESULT FinalConstruct();
@@ -139,41 +110,10 @@
     void uninit();
 
-    // IPerformanceCollector properties
-    STDMETHOD(COMGETTER(MetricNames)) (ComSafeArrayOut (BSTR, metricNames));
-
-    // IPerformanceCollector methods
-    STDMETHOD(GetMetrics) (ComSafeArrayIn (IN_BSTR, metricNames),
-                           ComSafeArrayIn (IUnknown *, objects),
-                           ComSafeArrayOut (IPerformanceMetric *, outMetrics));
-    STDMETHOD(SetupMetrics) (ComSafeArrayIn (IN_BSTR, metricNames),
-                             ComSafeArrayIn (IUnknown *, objects),
-                             ULONG aPeriod, ULONG aCount,
-                             ComSafeArrayOut (IPerformanceMetric *,
-                                              outMetrics));
-    STDMETHOD(EnableMetrics) (ComSafeArrayIn (IN_BSTR, metricNames),
-                              ComSafeArrayIn (IUnknown *, objects),
-                              ComSafeArrayOut (IPerformanceMetric *,
-                                               outMetrics));
-    STDMETHOD(DisableMetrics) (ComSafeArrayIn (IN_BSTR, metricNames),
-                               ComSafeArrayIn (IUnknown *, objects),
-                               ComSafeArrayOut (IPerformanceMetric *,
-                                                outMetrics));
-    STDMETHOD(QueryMetricsData) (ComSafeArrayIn (IN_BSTR, metricNames),
-                                 ComSafeArrayIn (IUnknown *, objects),
-                                 ComSafeArrayOut (BSTR, outMetricNames),
-                                 ComSafeArrayOut (IUnknown *, outObjects),
-                                 ComSafeArrayOut (BSTR, outUnits),
-                                 ComSafeArrayOut (ULONG, outScales),
-                                 ComSafeArrayOut (ULONG, outSequenceNumbers),
-                                 ComSafeArrayOut (ULONG, outDataIndices),
-                                 ComSafeArrayOut (ULONG, outDataLengths),
-                                 ComSafeArrayOut (LONG, outData));
-
     // public methods only for internal purposes
 
-    void registerBaseMetric (pm::BaseMetric *baseMetric);
-    void registerMetric (pm::Metric *metric);
-    void unregisterBaseMetricsFor (const ComPtr<IUnknown> &object, const Utf8Str name = "*");
-    void unregisterMetricsFor (const ComPtr<IUnknown> &object, const Utf8Str name = "*");
+    void registerBaseMetric(pm::BaseMetric *baseMetric);
+    void registerMetric(pm::Metric *metric);
+    void unregisterBaseMetricsFor(const ComPtr<IUnknown> &object, const Utf8Str name = "*");
+    void unregisterMetricsFor(const ComPtr<IUnknown> &object, const Utf8Str name = "*");
     void registerGuest(pm::CollectorGuest* pGuest);
     void unregisterGuest(pm::CollectorGuest* pGuest);
@@ -189,8 +129,39 @@
 
 private:
-    HRESULT toIPerformanceMetric(pm::Metric *src, IPerformanceMetric **dst);
-    HRESULT toIPerformanceMetric(pm::BaseMetric *src, IPerformanceMetric **dst);
 
-    static void staticSamplerCallback (RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+    // wrapped IPerformanceCollector properties
+    HRESULT getMetricNames(std::vector<com::Utf8Str> &aMetricNames);
+
+    // wrapped IPerformanceCollector methods
+    HRESULT getMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                       const std::vector<ComPtr<IUnknown> > &aObjects,
+                       std::vector<ComPtr<IPerformanceMetric> > &aMetrics);
+    HRESULT setupMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                         const std::vector<ComPtr<IUnknown> > &aObjects,
+                         ULONG aPeriod,
+                         ULONG aCount,
+                         std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+    HRESULT enableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                          const std::vector<ComPtr<IUnknown> > &aObjects,
+                          std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+    HRESULT disableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                           const std::vector<ComPtr<IUnknown> > &aObjects,
+                           std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics);
+    HRESULT queryMetricsData(const std::vector<com::Utf8Str> &aMetricNames,
+                             const std::vector<ComPtr<IUnknown> > &aObjects,
+                             std::vector<com::Utf8Str> &aReturnMetricNames,
+                             std::vector<ComPtr<IUnknown> > &aReturnObjects,
+                             std::vector<com::Utf8Str> &aReturnUnits,
+                             std::vector<ULONG> &aReturnScales,
+                             std::vector<ULONG> &aReturnSequenceNumbers,
+                             std::vector<ULONG> &aReturnDataIndices,
+                             std::vector<ULONG> &aReturnDataLengths,
+                             std::vector<LONG> &aReturnData);
+
+
+    HRESULT toIPerformanceMetric(pm::Metric *src, ComPtr<IPerformanceMetric> &dst);
+    HRESULT toIPerformanceMetric(pm::BaseMetric *src, ComPtr<IPerformanceMetric> &dst);
+
+    static void staticSamplerCallback(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
     void samplerCallback(uint64_t iTick);
 
Index: /trunk/src/VBox/Main/src-server/Performance.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/Performance.cpp	(revision 56586)
+++ /trunk/src/VBox/Main/src-server/Performance.cpp	(revision 56587)
@@ -1333,69 +1333,13 @@
 }
 
-Filter::Filter(ComSafeArrayIn(IN_BSTR, metricNames),
-               ComSafeArrayIn(IUnknown *, objects))
-{
-    /*
-     * Let's work around null/empty safe array mess. I am not sure there is
-     * a way to pass null arrays via webservice, I haven't found one. So I
-     * guess the users will be forced to use empty arrays instead. Constructing
-     * an empty SafeArray is a bit awkward, so what we do in this method is
-     * actually convert null arrays to empty arrays and pass them down to
-     * init() method. If someone knows how to do it better, please be my guest,
-     * fix it.
-     */
-    if (ComSafeArrayInIsNull(metricNames))
-    {
-        com::SafeArray<BSTR> nameArray;
-        if (ComSafeArrayInIsNull(objects))
-        {
-            com::SafeIfaceArray<IUnknown> objectArray;
-            objectArray.reset(0);
-            init(ComSafeArrayAsInParam(nameArray),
-                 ComSafeArrayAsInParam(objectArray));
-        }
-        else
-        {
-            com::SafeIfaceArray<IUnknown> objectArray(ComSafeArrayInArg(objects));
-            init(ComSafeArrayAsInParam(nameArray),
-                 ComSafeArrayAsInParam(objectArray));
-        }
-    }
-    else
-    {
-        com::SafeArray<IN_BSTR> nameArray(ComSafeArrayInArg(metricNames));
-        if (ComSafeArrayInIsNull(objects))
-        {
-            com::SafeIfaceArray<IUnknown> objectArray;
-            objectArray.reset(0);
-            init(ComSafeArrayAsInParam(nameArray),
-                 ComSafeArrayAsInParam(objectArray));
-        }
-        else
-        {
-            com::SafeIfaceArray<IUnknown> objectArray(ComSafeArrayInArg(objects));
-            init(ComSafeArrayAsInParam(nameArray),
-                 ComSafeArrayAsInParam(objectArray));
-        }
-    }
-}
-
-Filter::Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject)
-{
-    processMetricList(name, aObject);
-}
-
-void Filter::init(ComSafeArrayIn(IN_BSTR, metricNames),
-                  ComSafeArrayIn(IUnknown *, objects))
-{
-    com::SafeArray<IN_BSTR> nameArray(ComSafeArrayInArg(metricNames));
-    com::SafeIfaceArray<IUnknown> objectArray(ComSafeArrayInArg(objects));
-
-    if (!objectArray.size())
-    {
-        if (nameArray.size())
-        {
-            for (size_t i = 0; i < nameArray.size(); ++i)
-                processMetricList(com::Utf8Str(nameArray[i]), ComPtr<IUnknown>());
+Filter::Filter(const std::vector<com::Utf8Str> &metricNames,
+               const std::vector<ComPtr<IUnknown> > &objects)
+{
+    if (!objects.size())
+    {
+        if (metricNames.size())
+        {
+            for (size_t i = 0; i < metricNames.size(); ++i)
+                processMetricList(metricNames[i], ComPtr<IUnknown>());
         }
         else
@@ -1404,18 +1348,23 @@
     else
     {
-        for (size_t i = 0; i < objectArray.size(); ++i)
-            switch (nameArray.size())
+        for (size_t i = 0; i < objects.size(); ++i)
+            switch (metricNames.size())
             {
                 case 0:
-                    processMetricList("*", objectArray[i]);
+                    processMetricList("*", objects[i]);
                     break;
                 case 1:
-                    processMetricList(com::Utf8Str(nameArray[0]), objectArray[i]);
+                    processMetricList(metricNames[0], objects[i]);
                     break;
                 default:
-                    processMetricList(com::Utf8Str(nameArray[i]), objectArray[i]);
+                    processMetricList(metricNames[i], objects[i]);
                     break;
             }
     }
+}
+
+Filter::Filter(const com::Utf8Str &name, const ComPtr<IUnknown> &aObject)
+{
+    processMetricList(name, aObject);
 }
 
Index: /trunk/src/VBox/Main/src-server/PerformanceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/PerformanceImpl.cpp	(revision 56586)
+++ /trunk/src/VBox/Main/src-server/PerformanceImpl.cpp	(revision 56587)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2008-2012 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -190,8 +190,7 @@
 
     /* Start resource usage sampler */
-    int vrc = RTTimerLRCreate (&m.sampler, VBOX_USAGE_SAMPLER_MIN_INTERVAL,
-                               &PerformanceCollector::staticSamplerCallback, this);
-    AssertMsgRC (vrc, ("Failed to create resource usage "
-                       "sampling timer(%Rra)\n", vrc));
+    int vrc = RTTimerLRCreate(&m.sampler, VBOX_USAGE_SAMPLER_MIN_INTERVAL,
+                              &PerformanceCollector::staticSamplerCallback, this);
+    AssertMsgRC(vrc, ("Failed to create resource usage sampling timer(%Rra)\n", vrc));
     if (RT_FAILURE(vrc))
         rc = E_FAIL;
@@ -244,7 +243,6 @@
 
     /* Destroy resource usage sampler */
-    int vrc = RTTimerLRDestroy (m.sampler);
-    AssertMsgRC (vrc, ("Failed to destroy resource usage "
-                       "sampling timer (%Rra)\n", vrc));
+    int vrc = RTTimerLRDestroy(m.sampler);
+    AssertMsgRC(vrc, ("Failed to destroy resource usage sampling timer (%Rra)\n", vrc));
     m.sampler = NULL;
 
@@ -263,22 +261,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-STDMETHODIMP PerformanceCollector::COMGETTER(MetricNames)(ComSafeArrayOut(BSTR, theMetricNames))
-{
-    if (ComSafeArrayOutIsNull(theMetricNames))
-        return E_POINTER;
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
+HRESULT PerformanceCollector::getMetricNames(std::vector<com::Utf8Str> &aMetricNames)
+{
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    com::SafeArray<BSTR> metricNames(RT_ELEMENTS(g_papcszMetricNames));
+    aMetricNames.resize(RT_ELEMENTS(g_papcszMetricNames));
     for (size_t i = 0; i < RT_ELEMENTS(g_papcszMetricNames); i++)
-    {
-        Bstr tmp(g_papcszMetricNames[i]); /* gcc-3.3 cruft */
-        tmp.cloneTo(&metricNames[i]);
-    }
-    //gMetricNames.detachTo(ComSafeArrayOutArg(theMetricNames));
-    metricNames.detachTo(ComSafeArrayOutArg(theMetricNames));
+        aMetricNames[i] = g_papcszMetricNames[i];
 
     return S_OK;
@@ -288,23 +275,23 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-HRESULT PerformanceCollector::toIPerformanceMetric(pm::Metric *src, IPerformanceMetric **dst)
+HRESULT PerformanceCollector::toIPerformanceMetric(pm::Metric *src, ComPtr<IPerformanceMetric> &dst)
 {
     ComObjPtr<PerformanceMetric> metric;
     HRESULT rc = metric.createObject();
     if (SUCCEEDED(rc))
-        rc = metric->init (src);
+        rc = metric->init(src);
     AssertComRCReturnRC(rc);
-    metric.queryInterfaceTo(dst);
+    dst = metric;
     return rc;
 }
 
-HRESULT PerformanceCollector::toIPerformanceMetric(pm::BaseMetric *src, IPerformanceMetric **dst)
+HRESULT PerformanceCollector::toIPerformanceMetric(pm::BaseMetric *src, ComPtr<IPerformanceMetric> &dst)
 {
     ComObjPtr<PerformanceMetric> metric;
     HRESULT rc = metric.createObject();
     if (SUCCEEDED(rc))
-        rc = metric->init (src);
+        rc = metric->init(src);
     AssertComRCReturnRC(rc);
-    metric.queryInterfaceTo(dst);
+    dst = metric;
     return rc;
 }
@@ -318,18 +305,11 @@
 }
 
-STDMETHODIMP PerformanceCollector::GetMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
-                                              ComSafeArrayIn(IUnknown *, objects),
-                                              ComSafeArrayOut(IPerformanceMetric *, outMetrics))
-{
-    LogFlowThisFuncEnter();
-    //LogFlowThisFunc(("mState=%d, mType=%d\n", mState, mType));
-
+HRESULT PerformanceCollector::getMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                                         const std::vector<ComPtr<IUnknown> > &aObjects,
+                                         std::vector<ComPtr<IPerformanceMetric> > &aMetrics)
+{
     HRESULT rc = S_OK;
 
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    pm::Filter filter (ComSafeArrayInArg (metricNames),
-                       ComSafeArrayInArg (objects));
+    pm::Filter filter(aMetricNames, aObjects);
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -338,8 +318,8 @@
     MetricList::iterator it;
     for (it = m.metrics.begin(); it != m.metrics.end(); ++it)
-        if (filter.match ((*it)->getObject(), (*it)->getName()))
-            filteredMetrics.push_back (*it);
-
-    com::SafeIfaceArray<IPerformanceMetric> retMetrics (filteredMetrics.size());
+        if (filter.match((*it)->getObject(), (*it)->getName()))
+            filteredMetrics.push_back(*it);
+
+    aMetrics.resize(filteredMetrics.size());
     int i = 0;
     for (it = filteredMetrics.begin(); it != filteredMetrics.end(); ++it)
@@ -348,26 +328,19 @@
         rc = metric.createObject();
         if (SUCCEEDED(rc))
-            rc = metric->init (*it);
+            rc = metric->init(*it);
         AssertComRCReturnRC(rc);
-        LogFlow (("PerformanceCollector::GetMetrics() store a metric at "
-                  "retMetrics[%d]...\n", i));
-        metric.queryInterfaceTo(&retMetrics[i++]);
+        LogFlow(("PerformanceCollector::GetMetrics() store a metric at retMetrics[%d]...\n", i));
+        aMetrics[i++] = metric;
     }
-    retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
-    LogFlowThisFuncLeave();
     return rc;
 }
 
-STDMETHODIMP PerformanceCollector::SetupMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
-                                                ComSafeArrayIn(IUnknown *, objects),
-                                                ULONG aPeriod,
-                                                ULONG aCount,
-                                                ComSafeArrayOut(IPerformanceMetric *, outMetrics))
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    pm::Filter filter(ComSafeArrayInArg (metricNames),
-                      ComSafeArrayInArg (objects));
+HRESULT PerformanceCollector::setupMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                                           const std::vector<ComPtr<IUnknown> > &aObjects,
+                                           ULONG aPeriod,
+                                           ULONG aCount,
+                                           std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics)
+{
+    pm::Filter filter(aMetricNames, aObjects);
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -379,11 +352,11 @@
         if (filter.match((*it)->getObject(), (*it)->getName()))
         {
-            LogFlow (("PerformanceCollector::SetupMetrics() setting period to %u,"
-                      " count to %u for %s\n", aPeriod, aCount, (*it)->getName()));
+            LogFlow(("PerformanceCollector::SetupMetrics() setting period to %u, count to %u for %s\n",
+                     aPeriod, aCount, (*it)->getName()));
             (*it)->init(aPeriod, aCount);
             if (aPeriod == 0 || aCount == 0)
             {
-                LogFlow (("PerformanceCollector::SetupMetrics() disabling %s\n",
-                          (*it)->getName()));
+                LogFlow(("PerformanceCollector::SetupMetrics() disabling %s\n",
+                         (*it)->getName()));
                 rc = (*it)->disable();
                 if (FAILED(rc))
@@ -392,6 +365,6 @@
             else
             {
-                LogFlow (("PerformanceCollector::SetupMetrics() enabling %s\n",
-                          (*it)->getName()));
+                LogFlow(("PerformanceCollector::SetupMetrics() enabling %s\n",
+                         (*it)->getName()));
                 rc = (*it)->enable();
                 if (FAILED(rc))
@@ -401,12 +374,9 @@
         }
 
-    com::SafeIfaceArray<IPerformanceMetric> retMetrics(filteredMetrics.size());
+    aAffectedMetrics.resize(filteredMetrics.size());
     int i = 0;
     for (it = filteredMetrics.begin();
          it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
-        rc = toIPerformanceMetric(*it, &retMetrics[i++]);
-    retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
-
-    LogFlowThisFuncLeave();
+        rc = toIPerformanceMetric(*it, aAffectedMetrics[i++]);
 
     if (FAILED(rc))
@@ -416,13 +386,9 @@
 }
 
-STDMETHODIMP PerformanceCollector::EnableMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
-                                                 ComSafeArrayIn(IUnknown *, objects),
-                                                 ComSafeArrayOut(IPerformanceMetric *, outMetrics))
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    pm::Filter filter(ComSafeArrayInArg(metricNames),
-                      ComSafeArrayInArg(objects));
+HRESULT PerformanceCollector::enableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                                            const std::vector<ComPtr<IUnknown> > &aObjects,
+                                            std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics)
+{
+    pm::Filter filter(aMetricNames, aObjects);
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Write lock is not needed atm since we are */
@@ -442,10 +408,9 @@
         }
 
-    com::SafeIfaceArray<IPerformanceMetric> retMetrics(filteredMetrics.size());
+    aAffectedMetrics.resize(filteredMetrics.size());
     int i = 0;
     for (it = filteredMetrics.begin();
          it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
-        rc = toIPerformanceMetric(*it, &retMetrics[i++]);
-    retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
+        rc = toIPerformanceMetric(*it, aAffectedMetrics[i++]);
 
     LogFlowThisFuncLeave();
@@ -457,13 +422,9 @@
 }
 
-STDMETHODIMP PerformanceCollector::DisableMetrics(ComSafeArrayIn(IN_BSTR, metricNames),
-                                                  ComSafeArrayIn(IUnknown *, objects),
-                                                  ComSafeArrayOut(IPerformanceMetric *, outMetrics))
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    pm::Filter filter(ComSafeArrayInArg(metricNames),
-                      ComSafeArrayInArg(objects));
+HRESULT PerformanceCollector::disableMetrics(const std::vector<com::Utf8Str> &aMetricNames,
+                                             const std::vector<ComPtr<IUnknown> > &aObjects,
+                                             std::vector<ComPtr<IPerformanceMetric> > &aAffectedMetrics)
+{
+    pm::Filter filter(aMetricNames, aObjects);
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Write lock is not needed atm since we are */
@@ -483,10 +444,9 @@
         }
 
-    com::SafeIfaceArray<IPerformanceMetric> retMetrics(filteredMetrics.size());
+    aAffectedMetrics.resize(filteredMetrics.size());
     int i = 0;
     for (it = filteredMetrics.begin();
          it != filteredMetrics.end() && SUCCEEDED(rc); ++it)
-        rc = toIPerformanceMetric(*it, &retMetrics[i++]);
-    retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
+        rc = toIPerformanceMetric(*it, aAffectedMetrics[i++]);
 
     LogFlowThisFuncLeave();
@@ -498,20 +458,16 @@
 }
 
-STDMETHODIMP PerformanceCollector::QueryMetricsData(ComSafeArrayIn (IN_BSTR, metricNames),
-                                                    ComSafeArrayIn (IUnknown *, objects),
-                                                    ComSafeArrayOut(BSTR, outMetricNames),
-                                                    ComSafeArrayOut(IUnknown *, outObjects),
-                                                    ComSafeArrayOut(BSTR, outUnits),
-                                                    ComSafeArrayOut(ULONG, outScales),
-                                                    ComSafeArrayOut(ULONG, outSequenceNumbers),
-                                                    ComSafeArrayOut(ULONG, outDataIndices),
-                                                    ComSafeArrayOut(ULONG, outDataLengths),
-                                                    ComSafeArrayOut(LONG, outData))
-{
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    pm::Filter filter(ComSafeArrayInArg(metricNames),
-                      ComSafeArrayInArg(objects));
+HRESULT PerformanceCollector::queryMetricsData(const std::vector<com::Utf8Str> &aMetricNames,
+                                               const std::vector<ComPtr<IUnknown> > &aObjects,
+                                               std::vector<com::Utf8Str> &aReturnMetricNames,
+                                               std::vector<ComPtr<IUnknown> > &aReturnObjects,
+                                               std::vector<com::Utf8Str> &aReturnUnits,
+                                               std::vector<ULONG> &aReturnScales,
+                                               std::vector<ULONG> &aReturnSequenceNumbers,
+                                               std::vector<ULONG> &aReturnDataIndices,
+                                               std::vector<ULONG> &aReturnDataLengths,
+                                               std::vector<LONG> &aReturnData)
+{
+    pm::Filter filter(aMetricNames, aObjects);
 
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -522,7 +478,7 @@
     MetricList::iterator it;
     for (it = m.metrics.begin(); it != m.metrics.end(); ++it)
-        if (filter.match ((*it)->getObject(), (*it)->getName()))
+        if (filter.match((*it)->getObject(), (*it)->getName()))
         {
-            filteredMetrics.push_back (*it);
+            filteredMetrics.push_back(*it);
             flatSize += (*it)->getLength();
         }
@@ -531,12 +487,12 @@
     size_t flatIndex = 0;
     size_t numberOfMetrics = filteredMetrics.size();
-    com::SafeArray<BSTR> retNames(numberOfMetrics);
-    com::SafeIfaceArray<IUnknown> retObjects(numberOfMetrics);
-    com::SafeArray<BSTR> retUnits(numberOfMetrics);
-    com::SafeArray<ULONG> retScales(numberOfMetrics);
-    com::SafeArray<ULONG> retSequenceNumbers(numberOfMetrics);
-    com::SafeArray<ULONG> retIndices(numberOfMetrics);
-    com::SafeArray<ULONG> retLengths(numberOfMetrics);
-    com::SafeArray<LONG> retData(flatSize);
+    aReturnMetricNames.resize(numberOfMetrics);
+    aReturnObjects.resize(numberOfMetrics);
+    aReturnUnits.resize(numberOfMetrics);
+    aReturnScales.resize(numberOfMetrics);
+    aReturnSequenceNumbers.resize(numberOfMetrics);
+    aReturnDataIndices.resize(numberOfMetrics);
+    aReturnDataLengths.resize(numberOfMetrics);
+    aReturnData.resize(flatSize);
 
     for (it = filteredMetrics.begin(); it != filteredMetrics.end(); ++it, ++i)
@@ -545,28 +501,18 @@
         /* @todo We may want to revise the query method to get rid of excessive alloc/memcpy calls. */
         (*it)->query(&values, &length, &sequenceNumber);
-        LogFlow (("PerformanceCollector::QueryMetricsData() querying metric %s "
-                  "returned %d values.\n", (*it)->getName(), length));
-        memcpy(retData.raw() + flatIndex, values, length * sizeof(*values));
+        LogFlow(("PerformanceCollector::QueryMetricsData() querying metric %s returned %d values.\n",
+                 (*it)->getName(), length));
+        memcpy(&aReturnData[flatIndex], values, length * sizeof(*values));
         RTMemFree(values);
-        Bstr tmp((*it)->getName());
-        tmp.detachTo(&retNames[i]);
-        (*it)->getObject().queryInterfaceTo(&retObjects[i]);
-        tmp = (*it)->getUnit();
-        tmp.detachTo(&retUnits[i]);
-        retScales[i] = (*it)->getScale();
-        retSequenceNumbers[i] = sequenceNumber;
-        retLengths[i] = length;
-        retIndices[i] = (ULONG)flatIndex;
+        aReturnMetricNames[i] = (*it)->getName();
+        aReturnObjects[i] = (*it)->getObject();
+        aReturnUnits[i] = (*it)->getUnit();
+        aReturnScales[i] = (*it)->getScale();
+        aReturnSequenceNumbers[i] = sequenceNumber;
+        aReturnDataIndices[i] = (ULONG)flatIndex;
+        aReturnDataLengths[i] = length;
         flatIndex += length;
     }
 
-    retNames.detachTo(ComSafeArrayOutArg(outMetricNames));
-    retObjects.detachTo(ComSafeArrayOutArg(outObjects));
-    retUnits.detachTo(ComSafeArrayOutArg(outUnits));
-    retScales.detachTo(ComSafeArrayOutArg(outScales));
-    retSequenceNumbers.detachTo(ComSafeArrayOutArg(outSequenceNumbers));
-    retIndices.detachTo(ComSafeArrayOutArg(outDataIndices));
-    retLengths.detachTo(ComSafeArrayOutArg(outDataLengths));
-    retData.detachTo(ComSafeArrayOutArg(outData));
     return S_OK;
 }
@@ -584,5 +530,5 @@
     Log7(("{%p} " LOG_FN_FMT ": obj=%p name=%s\n", this, __PRETTY_FUNCTION__,
           (void *)baseMetric->getObject(), baseMetric->getName()));
-    m.baseMetrics.push_back (baseMetric);
+    m.baseMetrics.push_back(baseMetric);
     //LogFlowThisFuncLeave();
 }
@@ -596,5 +542,5 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     Log7(("{%p} " LOG_FN_FMT ": obj=%p name=%s\n", this, __PRETTY_FUNCTION__, (void *)metric->getObject(), metric->getName()));
-    m.metrics.push_back (metric);
+    m.metrics.push_back(metric);
     //LogFlowThisFuncLeave();
 }
@@ -692,5 +638,5 @@
                                                  uint64_t iTick)
 {
-    AssertReturnVoid (pvUser != NULL);
+    AssertReturnVoid(pvUser != NULL);
     PerformanceCollector *collector = static_cast <PerformanceCollector *> (pvUser);
     Assert(collector->mMagic == MAGIC);
@@ -698,5 +644,5 @@
         collector->samplerCallback(iTick);
 
-    NOREF (hTimerLR);
+    NOREF(hTimerLR);
 }
 
@@ -775,6 +721,6 @@
 
     /* Finally, collect the data */
-    std::for_each (toBeCollected.begin(), toBeCollected.end(),
-                   std::mem_fun (&pm::BaseMetric::collect));
+    std::for_each(toBeCollected.begin(), toBeCollected.end(),
+                  std::mem_fun(&pm::BaseMetric::collect));
     Log4(("{%p} " LOG_FN_FMT ": LEAVE\n", this, __PRETTY_FUNCTION__));
 }
@@ -806,5 +752,5 @@
     LogFlowThisFunc(("\n"));
 
-    uninit ();
+    uninit();
 
     BaseFinalRelease();
@@ -816,4 +762,8 @@
 HRESULT PerformanceMetric::init(pm::Metric *aMetric)
 {
+    /* Enclose the state transition NotReady->InInit->Ready */
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
     m.name        = aMetric->getName();
     m.object      = aMetric->getObject();
@@ -824,4 +774,6 @@
     m.min         = aMetric->getMinValue();
     m.max         = aMetric->getMaxValue();
+
+    autoInitSpan.setSucceeded();
     return S_OK;
 }
@@ -829,4 +781,8 @@
 HRESULT PerformanceMetric::init(pm::BaseMetric *aMetric)
 {
+    /* Enclose the state transition NotReady->InInit->Ready */
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
     m.name        = aMetric->getName();
     m.object      = aMetric->getObject();
@@ -837,4 +793,6 @@
     m.min         = aMetric->getMinValue();
     m.max         = aMetric->getMaxValue();
+
+    autoInitSpan.setSucceeded();
     return S_OK;
 }
@@ -842,54 +800,67 @@
 void PerformanceMetric::uninit()
 {
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(MetricName)(BSTR *aMetricName)
-{
-    /// @todo (r=dmik) why do all these getters not do AutoCaller and
-    /// AutoReadLock? Is the underlying metric a constant object?
-
-    m.name.cloneTo(aMetricName);
-    return S_OK;
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(Object)(IUnknown **anObject)
-{
-    m.object.queryInterfaceTo(anObject);
-    return S_OK;
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(Description)(BSTR *aDescription)
-{
-    m.description.cloneTo(aDescription);
-    return S_OK;
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(Period)(ULONG *aPeriod)
-{
+    /* Enclose the state transition Ready->InUninit->NotReady */
+    AutoUninitSpan autoUninitSpan(this);
+    if (autoUninitSpan.uninitDone())
+    {
+        LogFlowThisFunc(("Already uninitialized.\n"));
+        LogFlowThisFuncLeave();
+        return;
+    }
+}
+
+HRESULT PerformanceMetric::getMetricName(com::Utf8Str &aMetricName)
+{
+    /* this is const, no need to lock */
+    aMetricName = m.name;
+    return S_OK;
+}
+
+HRESULT PerformanceMetric::getObject(ComPtr<IUnknown> &aObject)
+{
+    /* this is const, no need to lock */
+    aObject = m.object;
+    return S_OK;
+}
+
+HRESULT PerformanceMetric::getDescription(com::Utf8Str &aDescription)
+{
+    /* this is const, no need to lock */
+    aDescription = m.description;
+    return S_OK;
+}
+
+HRESULT PerformanceMetric::getPeriod(ULONG *aPeriod)
+{
+    /* this is const, no need to lock */
     *aPeriod = m.period;
     return S_OK;
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(Count)(ULONG *aCount)
-{
+HRESULT PerformanceMetric::getCount(ULONG *aCount)
+{
+    /* this is const, no need to lock */
     *aCount = m.count;
     return S_OK;
 }
 
-STDMETHODIMP PerformanceMetric::COMGETTER(Unit)(BSTR *aUnit)
-{
-    m.unit.cloneTo(aUnit);
-    return S_OK;
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(MinimumValue)(LONG *aMinValue)
-{
-    *aMinValue = m.min;
-    return S_OK;
-}
-
-STDMETHODIMP PerformanceMetric::COMGETTER(MaximumValue)(LONG *aMaxValue)
-{
-    *aMaxValue = m.max;
+HRESULT PerformanceMetric::getUnit(com::Utf8Str &aUnit)
+{
+    /* this is const, no need to lock */
+    aUnit = m.unit;
+    return S_OK;
+}
+
+HRESULT PerformanceMetric::getMinimumValue(LONG *aMinimumValue)
+{
+    /* this is const, no need to lock */
+    *aMinimumValue = m.min;
+    return S_OK;
+}
+
+HRESULT PerformanceMetric::getMaximumValue(LONG *aMaximumValue)
+{
+    /* this is const, no need to lock */
+    *aMaximumValue = m.max;
     return S_OK;
 }
Index: /trunk/src/VBox/Main/src-server/xpcom/server.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 56586)
+++ /trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 56587)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2004-2014 Oracle Corporation
+ * Copyright (C) 2004-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -114,15 +114,4 @@
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ProgressProxy, IProgress)
 
-#ifdef VBOX_WITH_USB
-
-#endif
-
-#ifdef VBOX_WITH_RESOURCE_USAGE_API
-NS_DECL_CLASSINFO(PerformanceCollector)
-NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PerformanceCollector, IPerformanceCollector)
-NS_DECL_CLASSINFO(PerformanceMetric)
-NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PerformanceMetric, IPerformanceMetric)
-#endif /* VBOX_WITH_RESOURCE_USAGE_API */
-
 ////////////////////////////////////////////////////////////////////////////////
 
