Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 45517)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 45518)
@@ -45,5 +45,5 @@
 # Construct VBOX_MAIN_DEFS
 ## @todo eliminate or expand VBOX_MAIN_DEFS.
-VBOX_MAIN_DEFS   = 
+VBOX_MAIN_DEFS   =
 ifneq ($(KBUILD_TARGET),win)
  ifndef VBOX_WITH_XPCOM
@@ -162,4 +162,28 @@
 docs:                $(PATH_TARGET)/docs.Main
 endif
+
+
+#
+# Generate library with API class wrappers from the XIDL file.
+#
+LIBRARIES += VBoxAPIWrap
+VBoxAPIWrap_TEMPLATE        = VBOXMAINLIB
+VBoxAPIWrap_SOURCES         = $(VBoxAPIWrap_GENERATEDCPP)
+VBoxAPIWrap_GENERATEDCPP    = $(filter %.cpp,$(VBoxAPIWrap_GENERATEDSOURCES))
+VBoxAPIWrap_GENERATEDSOURCES = $(addprefix $(VBoxAPIWrap_0_OUTDIR)/,$(VBoxAPIWrap_VBOX_APIWRAPPERFILES))
+VBoxAPIWrap_RAWSRC          = \
+	$(VBoxAPIWrap_0_OUTDIR)/apiwrappers
+VBoxAPIWrap_XSLT            = \
+	$(VBOX_PATH_MAIN_SRC)/idl/apiwrap-server.xsl
+VBoxAPIWrap_DEFS.win.x86 += _WIN32_WINNT=0x0500
+VBoxAPIWrap_DEFS.win.amd64 += _WIN32_WINNT=0x0510
+VBoxAPIWrap_INCS           += \
+	include
+VBoxAPIWrap_CLEAN           = \
+	$(wildcard $(VBoxAPIWrap_0_OUTDIR)/*.cpp) \
+	$(wildcard $(VBoxAPIWrap_0_OUTDIR)/*.h) \
+	$(VBoxAPIWrap_RAWSRC)
+VBoxAPIWrap_KMK = $(PATH_OUT)/vboxapiwrap.kmk
+include $(VBoxAPIWrap_KMK)
 
 
@@ -256,8 +280,11 @@
 VBoxSVC_CXXFLAGS = $(filter-out -Wno-unused,$(TEMPLATE_VBOXMAINEXE_CXXFLAGS))
 
+VBoxSVC_DEPS = $(filter %.h,$(VBoxAPIWrap_GENERATEDSOURCES))
+
 VBoxSVC_INCS = \
 	include \
 	$(VBoxSVC_0_OUTDIR) \
 	$(dir $(VBOX_XML_SCHEMADEFS_H)) \
+	$(VBoxAPIWrap_0_OUTDIR) \
 	.
 VBoxSVC_INCS.win = \
@@ -269,4 +296,5 @@
 
 VBoxSVC_LIBS += \
+	$(PATH_STAGE_LIB)/VBoxAPIWrap$(VBOX_SUFF_LIB) \
 	$(PATH_STAGE_LIB)/SSMStandalone$(VBOX_SUFF_LIB) \
 	$(LIB_DDU)
@@ -544,7 +572,10 @@
 endif
 
+VBoxC_DEPS = $(filter %.h,$(VBoxAPIWrap_GENERATEDSOURCES))
+
 VBoxC_INCS          = \
 	include \
 	$(VBoxC_0_OUTDIR) \
+	$(VBoxAPIWrap_0_OUTDIR) \
 	$(dir $(VBOX_XML_SCHEMADEFS_H))
 VBoxC_INCS.win      = \
@@ -900,4 +931,23 @@
 	$(VBOX_PATH_MAIN_SRC)/glue/tests/Makefile=>Makefile
 
+# moved those rules to the end so that VBoxAPIWrap_0_OUTDIR can be expanded without $$ trickery
+$(VBoxAPIWrap_RAWSRC) \
++| $(VBoxAPIWrap_GENERATEDSOURCES): \
+		$(VBOX_XIDL_FILE) \
+		$(VBoxAPIWrap_XSLT) \
+		$(VBOX_FILESPLIT) \
+		| $$(dir $$@)
+	$(call MSG_L1,Generating C++ Server API wrapper files from XIDL)
+	$(QUIET)$(RM) -f $(filter-out $(VBoxAPIWrap_GENERATEDSOURCES),$(wildcard $(VBoxAPIWrap_0_OUTDIR)/*.cpp) $(wildcard $(VBoxAPIWrap_0_OUTDIR)/*.h))
+	$(QUIET)$(VBOX_XSLTPROC) --stringparam filelistonly "" -o $@ $(VBoxAPIWrap_XSLT) $<
+	$(QUIET)$(VBOX_FILESPLIT) $@ $(VBoxAPIWrap_0_OUTDIR)
+
+$(VBoxAPIWrap_KMK).ts +| $(VBoxAPIWrap_KMK): $(VBOX_XIDL_FILE) $(VBoxAPIWrap_XSLT)
+	$(call MSG_GENERATE,,$(VBoxAPIWrap_KMK))
+	$(QUIET)$(RM) -f $@
+	$(QUIET)$(MKDIR) -p $(@D)
+	$(QUIET)$(VBOX_XSLTPROC) --stringparam filelistonly VBoxAPIWrap_VBOX_APIWRAPPERFILES -o $@ $(VBoxAPIWrap_XSLT) $<
+	$(QUIET)$(CP) --changed -fv $@ $(VBoxAPIWrap_KMK)
+
 updatenls::
 	$(VBOX_LUPDATE) $(VBoxSVC_SOURCES) $(VBoxSVC_VBOX_HEADERS) -ts $(VBoxSVC_VBOX_TRANSLATIONS)
Index: trunk/src/VBox/Main/idl/apiwrap-server.xsl
===================================================================
--- trunk/src/VBox/Main/idl/apiwrap-server.xsl	(revision 45518)
+++ trunk/src/VBox/Main/idl/apiwrap-server.xsl	(revision 45518)
@@ -0,0 +1,1306 @@
+<?xml version="1.0"?>
+
+<!--
+    apiwrap-server.xsl:
+        XSLT stylesheet that generates C++ API wrappers (server side) from
+        VirtualBox.xidl.
+
+     Copyright (C) 2010-2013 Oracle Corporation
+
+     This file is part of VirtualBox Open Source Edition (OSE), as
+     available from http://www.virtualbox.org. This file is free software;
+     you can redistribute it and/or modify it under the terms of the GNU
+     General Public License (GPL) as published by the Free Software
+     Foundation, in version 2 as it comes in the "COPYING" file of the
+     VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+     hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+-->
+
+<xsl:stylesheet
+    version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:exsl="http://exslt.org/common"
+    extension-element-prefixes="exsl">
+
+<xsl:output method="text"/>
+
+<xsl:strip-space elements="*"/>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  global XSLT variables
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:variable name="G_xsltFilename" select="'apiwrap-server.xsl'"/>
+
+<xsl:include href="typemap-shared.inc.xsl"/>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+templates for file separation
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="interface" mode="listfile">
+    <xsl:param name="file"/>
+
+    <xsl:value-of select="concat('&#9;', $file, ' \&#10;')"/>
+</xsl:template>
+
+<xsl:template match="interface" mode="startfile">
+    <xsl:param name="file"/>
+
+    <xsl:value-of select="concat('&#10;// ##### BEGINFILE &quot;', $file, '&quot;&#10;')"/>
+</xsl:template>
+
+<xsl:template match="interface" mode="endfile">
+    <xsl:param name="file"/>
+
+    <xsl:value-of select="concat('&#10;// ##### ENDFILE &quot;', $file, '&quot;&#10;')"/>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+templates for file headers/footers
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template name="fileheader">
+    <xsl:param name="class"/>
+    <xsl:param name="name"/>
+    <xsl:param name="type"/>
+
+    <xsl:text>/** @file
+ *
+</xsl:text>
+    <xsl:value-of select="concat(' * VirtualBox API class wrapper ', $type, ' for I', $class, '.')"/>
+    <xsl:text>
+ *
+ * DO NOT EDIT! This is a generated file.
+ * Generated from: src/VBox/Main/idl/VirtualBox.xidl
+ * Generator: src/VBox/Main/idl/apiwrap-server.xsl
+ */
+
+/**
+ * Copyright (C) 2011-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+</xsl:text>
+</xsl:template>
+
+<xsl:template name="emitCOMInterfaces">
+    <xsl:param name="iface"/>
+
+    <xsl:value-of select="concat('        COM_INTERFACE_ENTRY(', $iface/@name, ')&#10;')"/>
+    <!-- now recurse to emit all base interfaces -->
+    <xsl:variable name="extends" select="$iface/@extends"/>
+    <xsl:if test="$extends and not($extends='$unknown') and not($extends='$dispatched') and not($extends='$errorinfo')">
+        <xsl:call-template name="emitCOMInterfaces">
+            <xsl:with-param name="iface" select="//interface[@name=$extends]"/>
+        </xsl:call-template>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template match="interface" mode="classheader">
+    <xsl:value-of select="concat('#ifndef ', substring(@name, 2), 'Wrap_H_&#10;')"/>
+    <xsl:value-of select="concat('#define ', substring(@name, 2), 'Wrap_H_')"/>
+    <xsl:text>
+
+#include "VirtualBoxBase.h"
+#include "Wrapper.h"
+
+</xsl:text>
+    <xsl:value-of select="concat('class ATL_NO_VTABLE ', substring(@name, 2), 'Wrap:')"/>
+    <xsl:text>
+    public VirtualBoxBase,
+</xsl:text>
+    <xsl:value-of select="concat('    VBOX_SCRIPTABLE_IMPL(', @name, ')&#10;')"/>
+    <xsl:text>{
+    Q_OBJECT
+
+public:
+</xsl:text>
+    <xsl:value-of select="concat('    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(', substring(@name, 2), 'Wrap, ', @name, ')&#10;')"/>
+    <xsl:value-of select="concat('    DECLARE_NOT_AGGREGATABLE(', substring(@name, 2), 'Wrap)&#10;')"/>
+    <xsl:text>    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+</xsl:text>
+    <xsl:value-of select="concat('    BEGIN_COM_MAP(', substring(@name, 2), 'Wrap)&#10;')"/>
+    <xsl:text>        COM_INTERFACE_ENTRY(ISupportErrorInfo)
+</xsl:text>
+    <xsl:call-template name="emitCOMInterfaces">
+        <xsl:with-param name="iface" select="."/>
+    </xsl:call-template>
+    <xsl:value-of select="concat('        COM_INTERFACE_ENTRY2(IDispatch, ', @name, ')&#10;')"/>
+    <xsl:text>    END_COM_MAP()
+
+</xsl:text>
+    <xsl:value-of select="concat('    DECLARE_EMPTY_CTOR_DTOR(', substring(@name, 2), 'Wrap)&#10;')"/>
+</xsl:template>
+
+<xsl:template match="interface" mode="classfooter">
+    <xsl:text>};
+
+</xsl:text>
+    <xsl:value-of select="concat('#endif // !', substring(@name, 2), 'Wrap_H_&#10;')"/>
+</xsl:template>
+
+<xsl:template match="interface" mode="codeheader">
+    <xsl:value-of select="concat('#define LOG_GROUP_MAIN_OVERRIDE LOG_GROUP_MAIN_', translate(substring(@name, 2), $G_lowerCase, $G_upperCase), '&#10;&#10;')"/>
+    <xsl:value-of select="concat('#include &quot;', substring(@name, 2), 'Wrap.h&quot;&#10;')"/>
+    <xsl:text>#include "AutoCaller.h"
+#include "Logging.h"
+
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="interface" mode="codefooter">
+    <xsl:text>#ifdef VBOX_WITH_XPCOM
+</xsl:text>
+    <xsl:value-of select="concat('NS_DECL_CLASSINFO(', substring(@name, 2), 'Wrap)&#10;NS_IMPL_THREADSAFE_ISUPPORTS1_CI(', substring(@name, 2), 'Wrap, ', @name, ')&#10;')"/>
+    <xsl:text>#endif // VBOX_WITH_XPCOM
+</xsl:text>
+</xsl:template>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  templates for dealing with names and parameters
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template name="tospace">
+    <xsl:param name="str"/>
+    <xsl:value-of select="translate($str, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_', '                                                               ')"/>
+</xsl:template>
+
+<xsl:template name="translatepublictype">
+    <xsl:param name="type"/>
+    <xsl:param name="dir"/>
+
+    <!-- get C++ glue type from IDL type from table in typemap-shared.inc.xsl -->
+    <xsl:variable name="gluetypefield" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@gluename"/>
+    <xsl:choose>
+        <xsl:when test="$type='wstring' or $type='uuid'">
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                    <xsl:text>IN_BSTR</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>BSTR</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:when>
+        <xsl:when test="string-length($gluetypefield)">
+            <xsl:value-of select="$gluetypefield"/>
+        </xsl:when>
+        <xsl:when test="//enum[@name=$type]">
+            <xsl:value-of select="concat($type, '_T')"/>
+        </xsl:when>
+        <xsl:when test="$type='$unknown'">
+            <xsl:text>IUnknown *</xsl:text>
+        </xsl:when>
+        <xsl:when test="//interface[@name=$type]">
+            <xsl:variable name="thatif" select="//interface[@name=$type]"/>
+            <xsl:variable name="thatifname" select="$thatif/@name"/>
+            <xsl:value-of select="concat($thatifname, ' *')"/>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:call-template name="fatalError">
+                <xsl:with-param name="msg" select="concat('translatepublictype: Type &quot;', $type, '&quot; is not supported.')"/>
+            </xsl:call-template>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template name="translatewrappedtype">
+    <xsl:param name="type"/>
+    <xsl:param name="dir"/>
+    <xsl:param name="safearray"/>
+
+    <!-- get C++ wrap type from IDL type from table in typemap-shared.inc.xsl -->
+    <xsl:variable name="wraptypefield" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@gluename"/>
+    <xsl:choose>
+        <xsl:when test="$type='wstring'">
+            <xsl:if test="$dir='in' and not($safearray='yes')">
+                <xsl:text>const </xsl:text>
+            </xsl:if>
+            <xsl:text>com::Utf8Str &amp;</xsl:text>
+        </xsl:when>
+        <xsl:when test="$type='uuid'">
+            <xsl:if test="$dir='in'">
+                <xsl:text>const </xsl:text>
+            </xsl:if>
+            <xsl:text>com::Guid &amp;</xsl:text>
+        </xsl:when>
+        <xsl:when test="string-length($wraptypefield)">
+            <xsl:value-of select="$wraptypefield"/>
+        </xsl:when>
+        <xsl:when test="//enum[@name=$type]">
+            <xsl:value-of select="concat($type, '_T')"/>
+        </xsl:when>
+        <xsl:when test="$type='$unknown'">
+            <xsl:if test="$dir='in' and not($safearray='yes')">
+                <xsl:text>const </xsl:text>
+            </xsl:if>
+            <xsl:text>ComPtr&lt;IUnknown&gt; &amp;</xsl:text>
+        </xsl:when>
+        <xsl:when test="//interface[@name=$type]">
+            <xsl:variable name="thatif" select="//interface[@name=$type]"/>
+            <xsl:variable name="thatifname" select="$thatif/@name"/>
+            <xsl:if test="$dir='in' and not($safearray='yes')">
+                <xsl:text>const </xsl:text>
+            </xsl:if>
+            <xsl:value-of select="concat('ComPtr&lt;', $thatifname, '&gt; &amp;')"/>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:call-template name="fatalError">
+                <xsl:with-param name="msg" select="concat('translatewrappedtype: Type &quot;', $type, '&quot; is not supported.')"/>
+            </xsl:call-template>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template name="translatefmtspectype">
+    <xsl:param name="type"/>
+    <xsl:param name="dir"/>
+    <xsl:param name="safearray"/>
+    <xsl:param name="mod"/>
+
+    <!-- get C format string for IDL type from table in typemap-shared.inc.xsl -->
+    <xsl:variable name="wrapfmt" select="exsl:node-set($G_aSharedTypes)/type[@idlname=$type]/@gluefmt"/>
+    <xsl:choose>
+        <xsl:when test="$mod='ref' and $dir!='in'">
+            <xsl:text>%p</xsl:text>
+        </xsl:when>
+        <xsl:when test="$safearray='yes'">
+            <xsl:text>%zu</xsl:text>
+        </xsl:when>
+        <xsl:when test="string-length($wrapfmt)">
+            <xsl:value-of select="$wrapfmt"/>
+        </xsl:when>
+        <xsl:when test="//enum[@name=$type]">
+            <xsl:text>%RU32</xsl:text>
+        </xsl:when>
+        <xsl:when test="$type='$unknown'">
+            <xsl:text>%p</xsl:text>
+        </xsl:when>
+        <xsl:when test="//interface[@name=$type]">
+            <xsl:text>%p</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:call-template name="fatalError">
+                <xsl:with-param name="msg" select="concat('translatefmtcpectype: Type &quot;', $type, '&quot; is not supported.')"/>
+            </xsl:call-template>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="attribute/@type | param/@type" mode="public">
+    <xsl:param name="dir"/>
+
+    <xsl:variable name="gluetype">
+        <xsl:call-template name="translatepublictype">
+            <xsl:with-param name="type" select="."/>
+            <xsl:with-param name="dir" select="$dir"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:if test="../@safearray='yes'">
+        <xsl:choose>
+            <xsl:when test="$dir='in'">
+                <xsl:text>ComSafeArrayIn(</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+                <xsl:text>ComSafeArrayOut(</xsl:text>
+            </xsl:otherwise>
+        </xsl:choose>
+    </xsl:if>
+    <xsl:value-of select="$gluetype"/>
+    <xsl:choose>
+        <xsl:when test="../@safearray='yes'">
+            <xsl:text>, </xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:if test="substring($gluetype,string-length($gluetype))!='*'">
+                <xsl:text> </xsl:text>
+            </xsl:if>
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:value-of select="'*'"/>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>a</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="../@name"/>
+    </xsl:call-template>
+    <xsl:if test="../@safearray='yes'">
+        <xsl:value-of select="')'"/>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template match="attribute/@type | param/@type" mode="wrapped">
+    <xsl:param name="dir"/>
+
+    <xsl:variable name="wraptype">
+        <xsl:call-template name="translatewrappedtype">
+            <xsl:with-param name="type" select="."/>
+            <xsl:with-param name="dir" select="$dir"/>
+            <xsl:with-param name="safearray" select="../@safearray"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:choose>
+        <xsl:when test="../@safearray='yes'">
+            <xsl:if test="$dir='in'">
+                <xsl:text>const </xsl:text>
+            </xsl:if>
+            <xsl:text>std::vector&lt;</xsl:text>
+            <xsl:choose>
+                <xsl:when test="substring($wraptype,string-length($wraptype))='&amp;'">
+                    <xsl:variable name="wraptype2">
+                        <xsl:value-of select="substring($wraptype,1,string-length($wraptype)-2)"/>
+                    </xsl:variable>
+
+                    <xsl:choose>
+                        <xsl:when test="substring($wraptype2,string-length($wraptype2))='&gt;'">
+                            <xsl:value-of select="concat($wraptype2, ' ')"/>
+                        </xsl:when>
+                        <xsl:otherwise>
+                            <xsl:value-of select="$wraptype2"/>
+                        </xsl:otherwise>
+                    </xsl:choose>
+                </xsl:when>
+                <xsl:when test="substring($wraptype,string-length($wraptype))='&gt;'">
+                    <xsl:value-of select="concat($wraptype, ' ')"/>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:value-of select="$wraptype"/>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:text>&gt; &amp;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="$wraptype"/>
+            <xsl:if test="substring($wraptype,string-length($wraptype))!='&amp;'">
+                <xsl:if test="substring($wraptype,string-length($wraptype))!='*'">
+                    <xsl:text> </xsl:text>
+                </xsl:if>
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:value-of select="'*'"/>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>a</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="../@name"/>
+    </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="attribute/@type | param/@type" mode="logparamtext">
+    <xsl:param name="dir"/>
+    <xsl:param name="mod"/>
+
+    <xsl:if test="$mod!='ref' and ($dir='out' or $dir='ret')">
+        <xsl:text>*</xsl:text>
+    </xsl:if>
+    <xsl:text>a</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="../@name"/>
+    </xsl:call-template>
+    <xsl:text>=</xsl:text>
+    <xsl:call-template name="translatefmtspectype">
+        <xsl:with-param name="type" select="."/>
+        <xsl:with-param name="dir" select="$dir"/>
+        <xsl:with-param name="safearray" select="../@safearray"/>
+        <xsl:with-param name="mod" select="$mod"/>
+    </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="attribute/@type | param/@type" mode="logparamval">
+    <xsl:param name="dir"/>
+    <xsl:param name="mod"/>
+
+    <xsl:choose>
+        <xsl:when test="../@safearray='yes' and $mod!='ref'">
+            <xsl:text>ComSafeArraySize(</xsl:text>
+            <xsl:if test="$mod!='ref' and $dir!='in'">
+                <xsl:text>*</xsl:text>
+            </xsl:if>
+        </xsl:when>
+        <xsl:when test="$mod!='ref' and $dir!='in'">
+            <xsl:text>*</xsl:text>
+        </xsl:when>
+    </xsl:choose>
+    <xsl:text>a</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="../@name"/>
+    </xsl:call-template>
+    <xsl:choose>
+        <xsl:when test="../@safearray='yes' and $mod!='ref'">
+            <xsl:text>)</xsl:text>
+        </xsl:when>
+    </xsl:choose>
+</xsl:template>
+
+<xsl:template match="attribute/@type | param/@type" mode="paramvalconversion">
+    <xsl:param name="dir"/>
+
+    <xsl:variable name="gluetype">
+        <xsl:call-template name="translatepublictype">
+            <xsl:with-param name="type" select="."/>
+            <xsl:with-param name="dir" select="$dir"/>
+        </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="type" select="."/>
+    <xsl:variable name="thatif" select="../../../..//interface[@name=$type]"/>
+    <xsl:choose>
+        <xsl:when test="$type='$unknown'">
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>Array</xsl:text>
+            </xsl:if>
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                    <xsl:text>ComTypeInConverter&lt;IUnknown&gt;(</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>ComTypeOutConverter&lt;IUnknown&gt;(</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>ComSafeArrayInArg(</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>ComSafeArrayOutArg(</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:when>
+        <xsl:when test="$thatif">
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>Array</xsl:text>
+            </xsl:if>
+            <xsl:variable name="thatifname" select="$thatif/@name"/>
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                    <xsl:text>ComTypeInConverter</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>ComTypeOutConverter</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:value-of select="concat('&lt;', $thatifname, '&gt;(')"/>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>ComSafeArrayInArg(</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>ComSafeArrayOutArg(</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:when>
+        <xsl:when test="$type='wstring'">
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>Array</xsl:text>
+            </xsl:if>
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                    <xsl:text>BSTRInConverter(</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>BSTROutConverter(</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>ComSafeArrayInArg(</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>ComSafeArrayOutArg(</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:when>
+        <xsl:when test="$type='uuid'">
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>Array</xsl:text>
+            </xsl:if>
+            <xsl:choose>
+                <xsl:when test="$dir='in'">
+                    <xsl:text>UuidInConverter(</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>UuidOutConverter(</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>ComSafeArrayInArg(</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>ComSafeArrayOutArg(</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>Array</xsl:text>
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>InConverter</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>OutConverter</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+                <xsl:value-of select="concat('&lt;', $gluetype, '&gt;(')"/>
+                <xsl:choose>
+                    <xsl:when test="$dir='in'">
+                        <xsl:text>ComSafeArrayInArg(</xsl:text>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>ComSafeArrayOutArg(</xsl:text>
+                    </xsl:otherwise>
+                </xsl:choose>
+            </xsl:if>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text>a</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="../@name"/>
+    </xsl:call-template>
+    <xsl:choose>
+        <xsl:when test="$type='$unknown' or $thatif">
+            <xsl:choose>
+                <xsl:when test="../@safearray='yes'">
+                    <xsl:text>)).array()</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>).ptr()</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:when>
+        <xsl:when test="$type='wstring'">
+            <xsl:choose>
+                <xsl:when test="../@safearray='yes'">
+                    <xsl:text>)).array()</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>).str()</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:when>
+        <xsl:when test="$type='uuid'">
+            <xsl:choose>
+                <xsl:when test="../@safearray='yes'">
+                    <xsl:text>)).array()</xsl:text>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:text>).uuid()</xsl:text>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:if test="../@safearray='yes'">
+                <xsl:text>)).array()</xsl:text>
+            </xsl:if>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit attribute
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="attribute" mode="public">
+    <xsl:variable name="attrbasename">
+        <xsl:call-template name="capitalize">
+            <xsl:with-param name="str" select="@name"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:value-of select="concat('    STDMETHOD(COMGETTER(', $attrbasename, '))(')"/>
+    <xsl:apply-templates select="@type" mode="public">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text>);
+</xsl:text>
+
+    <xsl:if test="not(@readonly) or @readonly!='yes'">
+        <xsl:value-of select="concat('    STDMETHOD(COMSETTER(', $attrbasename, '))(')"/>
+        <xsl:apply-templates select="@type" mode="public">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <xsl:text>);
+</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template match="attribute" mode="wrapped">
+    <xsl:variable name="attrbasename">
+        <xsl:call-template name="capitalize">
+            <xsl:with-param name="str" select="@name"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:value-of select="concat('    virtual HRESULT get', $attrbasename, '(')"/>
+    <xsl:apply-templates select="@type" mode="wrapped">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text>) = 0;
+</xsl:text>
+
+    <xsl:if test="not(@readonly) or @readonly!='yes'">
+        <xsl:value-of select="concat('    virtual HRESULT set', $attrbasename, '(')"/>
+        <xsl:apply-templates select="@type" mode="wrapped">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <xsl:text>) = 0;
+</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template match="attribute" mode="code">
+    <xsl:param name="topclass"/>
+
+    <xsl:variable name="attrbasename">
+        <xsl:call-template name="capitalize">
+            <xsl:with-param name="str" select="@name"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:value-of select="concat('STDMETHODIMP ', $topclass, 'Wrap::COMGETTER(', $attrbasename, ')(')"/>
+    <xsl:apply-templates select="@type" mode="public">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text>)
+{
+    LogRelFlow(("{%p} %s: enter </xsl:text>
+    <xsl:apply-templates select="@type" mode="logparamtext">
+        <xsl:with-param name="dir" select="'out'"/>
+        <xsl:with-param name="mod" select="'ref'"/>
+    </xsl:apply-templates>
+    <xsl:text>\n", this, </xsl:text>
+    <xsl:value-of select="concat('&quot;', $topclass, '::get', $attrbasename, '&quot;, ')"/>
+    <xsl:apply-templates select="@type" mode="logparamval">
+        <xsl:with-param name="dir" select="'out'"/>
+        <xsl:with-param name="mod" select="'ref'"/>
+    </xsl:apply-templates>
+    <xsl:text>));
+
+    VirtualBoxBase::clearError();
+
+    HRESULT hrc;
+
+    try
+    {
+        CheckComArgOutPointerValidThrow(a</xsl:text>
+    <xsl:value-of select="$attrbasename"/>
+    <xsl:text>);
+
+        AutoCaller autoCaller(this);
+        if (FAILED(autoCaller.rc()))
+            throw autoCaller.rc();
+
+</xsl:text>
+    <xsl:value-of select="concat('        hrc = get', $attrbasename, '(')"/>
+    <xsl:apply-templates select="@type" mode="paramvalconversion">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text>);
+    }
+    catch (HRESULT hrc2)
+    {
+        hrc = hrc2;
+    }
+    catch (...)
+    {
+        hrc = VirtualBoxBase::handleUnexpectedExceptions(this, RT_SRC_POS);
+    }
+
+    LogRelFlow(("{%p} %s: leave </xsl:text>
+    <xsl:apply-templates select="@type" mode="logparamtext">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text> hrc=%Rhrc\n", this, </xsl:text>
+    <xsl:value-of select="concat('&quot;', $topclass, '::get', $attrbasename, '&quot;, ')"/>
+    <xsl:apply-templates select="@type" mode="logparamval">
+        <xsl:with-param name="dir" select="'out'"/>
+    </xsl:apply-templates>
+    <xsl:text>, hrc));
+    return hrc;
+}
+
+</xsl:text>
+    <xsl:if test="not(@readonly) or @readonly!='yes'">
+        <xsl:value-of select="concat('STDMETHODIMP ', $topclass, 'Wrap::COMSETTER(', $attrbasename, ')(')"/>
+        <xsl:apply-templates select="@type" mode="public">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <!-- @todo check in parameters if possible -->
+        <xsl:text>)
+{
+    LogRelFlow(("{%p} %s: enter </xsl:text>
+        <xsl:apply-templates select="@type" mode="logparamtext">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <xsl:text>\n", this, </xsl:text>
+        <xsl:value-of select="concat('&quot;', $topclass, '::set', $attrbasename, '&quot;, ')"/>
+        <xsl:apply-templates select="@type" mode="logparamval">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <xsl:text>));
+
+    VirtualBoxBase::clearError();
+
+    HRESULT hrc;
+
+    try
+    {
+        AutoCaller autoCaller(this);
+        if (FAILED(autoCaller.rc()))
+            throw autoCaller.rc();
+
+</xsl:text>
+        <xsl:value-of select="concat('        hrc = set', $attrbasename, '(')"/>
+        <xsl:apply-templates select="@type" mode="paramvalconversion">
+            <xsl:with-param name="dir" select="'in'"/>
+        </xsl:apply-templates>
+        <xsl:text>);
+    }
+    catch (HRESULT hrc2)
+    {
+        hrc = hrc2;
+    }
+    catch (...)
+    {
+        hrc = VirtualBoxBase::handleUnexpectedExceptions(this, RT_SRC_POS);
+    }
+
+    LogRelFlow(("{%p} %s: leave hrc=%Rhrc\n", this, </xsl:text>
+        <xsl:value-of select="concat('&quot;', $topclass, '::set', $attrbasename, '&quot;, ')"/>
+        <xsl:text>hrc));
+    return hrc;
+}
+
+</xsl:text>
+    </xsl:if>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit all attributes of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitAttributes">
+    <xsl:param name="iface"/>
+    <xsl:param name="topclass"/>
+    <xsl:param name="pmode"/>
+
+    <!-- first recurse to emit all base interfaces -->
+    <xsl:variable name="extends" select="$iface/@extends"/>
+    <xsl:if test="$extends and not($extends='$unknown') and not($extends='$dispatched') and not($extends='$errorinfo')">
+        <xsl:call-template name="emitAttributes">
+            <xsl:with-param name="iface" select="//interface[@name=$extends]"/>
+            <xsl:with-param name="topclass" select="$topclass"/>
+            <xsl:with-param name="pmode" select="$pmode"/>
+        </xsl:call-template>
+    </xsl:if>
+
+    <xsl:choose>
+        <xsl:when test="$pmode='code'">
+            <xsl:text>//
+</xsl:text>
+            <xsl:value-of select="concat('// ', $iface/@name, ' properties')"/>
+            <xsl:text>
+//
+
+</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="concat('&#10;    // ', $pmode, ' ', $iface/@name, ' properties&#10;')"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:choose>
+        <xsl:when test="$pmode='public'">
+            <xsl:apply-templates select="$iface/attribute" mode="public"/>
+        </xsl:when>
+        <xsl:when test="$pmode='wrapped'">
+            <xsl:apply-templates select="$iface/attribute" mode="wrapped"/>
+        </xsl:when>
+        <xsl:when test="$pmode='code'">
+            <xsl:apply-templates select="$iface/attribute" mode="code">
+                <xsl:with-param name="topclass" select="$topclass"/>
+            </xsl:apply-templates>
+        </xsl:when>
+        <xsl:otherwise/>
+    </xsl:choose>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit method
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="method" mode="public">
+    <xsl:variable name="methodindent">
+      <xsl:call-template name="tospace">
+          <xsl:with-param name="str" select="@name"/>
+      </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:text>    STDMETHOD(</xsl:text>
+    <xsl:call-template name="capitalize">
+        <xsl:with-param name="str" select="@name"/>
+    </xsl:call-template>
+    <xsl:text>)(</xsl:text>
+    <xsl:for-each select="param">
+        <xsl:apply-templates select="@type" mode="public">
+            <xsl:with-param name="dir" select="@dir"/>
+        </xsl:apply-templates>
+        <xsl:if test="not(position()=last())">
+            <xsl:text>,
+                </xsl:text>
+            <xsl:value-of select="$methodindent"/>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>);
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="method" mode="wrapped">
+    <xsl:variable name="methodindent">
+        <xsl:call-template name="tospace">
+            <xsl:with-param name="str" select="@name"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:text>    virtual HRESULT </xsl:text>
+    <xsl:call-template name="uncapitalize">
+        <xsl:with-param name="str" select="@name"/>
+    </xsl:call-template>
+    <xsl:text>(</xsl:text>
+    <xsl:for-each select="param">
+        <xsl:apply-templates select="@type" mode="wrapped">
+            <xsl:with-param name="dir" select="@dir"/>
+        </xsl:apply-templates>
+        <xsl:if test="not(position()=last())">
+            <xsl:text>,
+                     </xsl:text>
+            <xsl:value-of select="$methodindent"/>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>) = 0;
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="method" mode="code">
+    <xsl:param name="topclass"/>
+
+    <xsl:variable name="methodindent">
+      <xsl:call-template name="tospace">
+          <xsl:with-param name="str" select="@name"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="methodclassindent">
+      <xsl:call-template name="tospace">
+          <xsl:with-param name="str" select="concat($topclass, @name)"/>
+      </xsl:call-template>
+    </xsl:variable>
+    <xsl:variable name="methodbasename">
+        <xsl:call-template name="capitalize">
+            <xsl:with-param name="str" select="@name"/>
+        </xsl:call-template>
+    </xsl:variable>
+
+    <xsl:value-of select="concat('STDMETHODIMP ', $topclass, 'Wrap::', $methodbasename, '(')"/>
+    <xsl:for-each select="param">
+        <xsl:apply-templates select="@type" mode="public">
+            <xsl:with-param name="dir" select="@dir"/>
+        </xsl:apply-templates>
+        <xsl:if test="not(position()=last())">
+            <xsl:text>,
+                    </xsl:text>
+            <xsl:value-of select="$methodclassindent"/>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>)
+{
+    LogRelFlow(("{%p} %s:enter</xsl:text>
+    <xsl:for-each select="param">
+        <xsl:text> </xsl:text>
+        <xsl:apply-templates select="@type" mode="logparamtext">
+            <xsl:with-param name="dir" select="@dir"/>
+            <xsl:with-param name="mod" select="'ref'"/>
+        </xsl:apply-templates>
+    </xsl:for-each>
+    <xsl:text>\n", this</xsl:text>
+    <xsl:value-of select="concat(', &quot;', $topclass, '::', @name, '&quot;')"/>
+    <xsl:for-each select="param">
+        <xsl:text>, </xsl:text>
+        <xsl:apply-templates select="@type" mode="logparamval">
+            <xsl:with-param name="dir" select="@dir"/>
+            <xsl:with-param name="mod" select="'ref'"/>
+        </xsl:apply-templates>
+    </xsl:for-each>
+    <xsl:text>));
+
+    VirtualBoxBase::clearError();
+
+    HRESULT hrc;
+
+    try
+    {
+</xsl:text>
+    <!-- @todo check in parameters if possible -->
+    <xsl:for-each select="param">
+        <xsl:if test="@dir!='in'">
+            <xsl:text>        CheckComArgOutPointerValidThrow(a</xsl:text>
+            <xsl:call-template name="capitalize">
+                <xsl:with-param name="str" select="@name"/>
+            </xsl:call-template>
+            <xsl:text>);
+</xsl:text>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>
+        AutoCaller autoCaller(this);
+        if (FAILED(autoCaller.rc()))
+            throw autoCaller.rc();
+
+</xsl:text>
+    <xsl:value-of select="concat('        hrc = ', @name, '(')"/>
+    <xsl:for-each select="param">
+        <xsl:apply-templates select="@type" mode="paramvalconversion">
+            <xsl:with-param name="dir" select="@dir"/>
+        </xsl:apply-templates>
+        <xsl:if test="not(position()=last())">
+            <xsl:text>,
+               </xsl:text>
+            <xsl:value-of select="$methodindent"/>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>);
+    }
+    catch (HRESULT hrc2)
+    {
+        hrc = hrc2;
+    }
+    catch (...)
+    {
+        hrc = VirtualBoxBase::handleUnexpectedExceptions(this, RT_SRC_POS);
+    }
+
+    LogRelFlow(("{%p} %s: leave</xsl:text>
+    <xsl:for-each select="param">
+        <xsl:if test="@dir!='in'">
+            <xsl:text> </xsl:text>
+            <xsl:apply-templates select="@type" mode="logparamtext">
+                <xsl:with-param name="dir" select="@dir"/>
+            </xsl:apply-templates>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text> hrc=%Rhrc\n", this</xsl:text>
+    <xsl:value-of select="concat(', &quot;', $topclass, '::', @name, '&quot;')"/>
+    <xsl:for-each select="param">
+        <xsl:if test="@dir!='in'">
+            <xsl:text>, </xsl:text>
+            <xsl:apply-templates select="@type" mode="logparamval">
+                <xsl:with-param name="dir" select="@dir"/>
+            </xsl:apply-templates>
+        </xsl:if>
+    </xsl:for-each>
+    <xsl:text>, hrc));
+    return hrc;
+}
+
+</xsl:text>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit all methods of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitMethods">
+    <xsl:param name="iface"/>
+    <xsl:param name="topclass"/>
+    <xsl:param name="pmode"/>
+
+    <!-- first recurse to emit all base interfaces -->
+    <xsl:variable name="extends" select="$iface/@extends"/>
+    <xsl:if test="$extends and not($extends='$unknown') and not($extends='$dispatched') and not($extends='$errorinfo')">
+        <xsl:call-template name="emitMethods">
+            <xsl:with-param name="iface" select="//interface[@name=$extends]"/>
+            <xsl:with-param name="topclass" select="$topclass"/>
+            <xsl:with-param name="pmode" select="$pmode"/>
+        </xsl:call-template>
+    </xsl:if>
+
+    <xsl:choose>
+        <xsl:when test="$pmode='code'">
+            <xsl:text>//
+</xsl:text>
+            <xsl:value-of select="concat('// ', $iface/@name, ' methods')"/>
+            <xsl:text>
+//
+
+</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="concat('&#10;    // ', $pmode, ' ', $iface/@name, ' methods&#10;')"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:choose>
+        <xsl:when test="$pmode='public'">
+            <xsl:apply-templates select="$iface/method" mode="public"/>
+        </xsl:when>
+        <xsl:when test="$pmode='wrapped'">
+            <xsl:apply-templates select="$iface/method" mode="wrapped"/>
+        </xsl:when>
+        <xsl:when test="$pmode='code'">
+            <xsl:apply-templates select="$iface/method" mode="code">
+                <xsl:with-param name="topclass" select="$topclass"/>
+            </xsl:apply-templates>
+        </xsl:when>
+        <xsl:otherwise/>
+    </xsl:choose>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit all attributes and methods declarations of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitInterfaceDecls">
+    <xsl:param name="iface"/>
+    <xsl:param name="pmode"/>
+
+    <!-- attributes -->
+    <xsl:call-template name="emitAttributes">
+        <xsl:with-param name="iface" select="$iface"/>
+        <xsl:with-param name="pmode" select="$pmode"/>
+    </xsl:call-template>
+
+    <!-- methods -->
+    <xsl:call-template name="emitMethods">
+        <xsl:with-param name="iface" select="$iface"/>
+        <xsl:with-param name="pmode" select="$pmode"/>
+    </xsl:call-template>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit auxiliary method declarations of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitAuxMethodDecls">
+    <xsl:param name="iface"/>
+    <!-- currently nothing, maybe later some generic FinalConstruct/... helper declaration for ComObjPtr -->
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit the header file of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitHeader">
+    <xsl:param name="iface"/>
+
+    <xsl:variable name="filename" select="concat(substring(@name, 2), 'Wrap.h')"/>
+
+    <xsl:choose>
+        <xsl:when test="$filelistonly=''">
+            <xsl:apply-templates select="$iface" mode="startfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+            <xsl:call-template name="fileheader">
+                <xsl:with-param name="name" select="$filename"/>
+                <xsl:with-param name="class" select="substring(@name, 2)"/>
+                <xsl:with-param name="type" select="'header'"/>
+            </xsl:call-template>
+            <xsl:apply-templates select="." mode="classheader"/>
+
+            <!-- interface attributes/methods (public) -->
+            <xsl:call-template name="emitInterfaceDecls">
+                <xsl:with-param name="iface" select="$iface"/>
+                <xsl:with-param name="pmode" select="'public'"/>
+            </xsl:call-template>
+
+            <!-- auxiliary methods (public) -->
+            <xsl:call-template name="emitAuxMethodDecls">
+                <xsl:with-param name="iface" select="$iface"/>
+            </xsl:call-template>
+
+            <!-- switch to private -->
+            <xsl:text>
+private:</xsl:text>
+
+            <!-- wrapped interface attributes/methods (private) -->
+            <xsl:call-template name="emitInterfaceDecls">
+                <xsl:with-param name="iface" select="$iface"/>
+                <xsl:with-param name="pmode" select="'wrapped'"/>
+            </xsl:call-template>
+
+            <xsl:apply-templates select="." mode="classfooter"/>
+            <xsl:apply-templates select="$iface" mode="endfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:apply-templates select="$iface" mode="listfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit all attributes and methods definitions of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitInterfaceDefs">
+    <xsl:param name="iface"/>
+
+    <xsl:value-of select="concat('DEFINE_EMPTY_CTOR_DTOR(', substring($iface/@name, 2), 'Wrap)&#10;&#10;')"/>
+
+    <!-- attributes -->
+    <xsl:call-template name="emitAttributes">
+        <xsl:with-param name="iface" select="$iface"/>
+        <xsl:with-param name="topclass" select="substring($iface/@name, 2)"/>
+        <xsl:with-param name="pmode" select="'code'"/>
+    </xsl:call-template>
+
+    <!-- methods -->
+    <xsl:call-template name="emitMethods">
+        <xsl:with-param name="iface" select="$iface"/>
+        <xsl:with-param name="topclass" select="substring($iface/@name, 2)"/>
+        <xsl:with-param name="pmode" select="'code'"/>
+    </xsl:call-template>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit auxiliary method declarations of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitAuxMethodDefs">
+    <xsl:param name="iface"/>
+    <!-- currently nothing, maybe later some generic FinalConstruct/... implementation -->
+</xsl:template>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  emit the code file of an interface
+  - - - - - - - - - - - - - - - - - - - - - - -->
+<xsl:template name="emitCode">
+    <xsl:param name="iface"/>
+
+    <xsl:variable name="filename" select="concat(substring(@name, 2), 'Wrap.cpp')"/>
+
+    <xsl:choose>
+        <xsl:when test="$filelistonly=''">
+            <xsl:apply-templates select="$iface" mode="startfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+            <xsl:call-template name="fileheader">
+                <xsl:with-param name="name" select="$filename"/>
+                <xsl:with-param name="class" select="substring(@name, 2)"/>
+                <xsl:with-param name="type" select="'code'"/>
+            </xsl:call-template>
+            <xsl:apply-templates select="." mode="codeheader"/>
+
+            <!-- @todo special thread logging for API methods returning IProgress??? would be very usefulcurrently nothing, maybe later some generic FinalConstruct/... implementation -->
+
+            <!-- interface attributes/methods (public) -->
+            <xsl:call-template name="emitInterfaceDefs">
+                <xsl:with-param name="iface" select="$iface"/>
+            </xsl:call-template>
+
+            <!-- auxiliary methods (public) -->
+            <xsl:call-template name="emitAuxMethodDefs">
+                <xsl:with-param name="iface" select="$iface"/>
+            </xsl:call-template>
+
+            <xsl:apply-templates select="." mode="codefooter"/>
+            <xsl:apply-templates select="$iface" mode="endfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:apply-templates select="$iface" mode="listfile">
+                <xsl:with-param name="file" select="$filename"/>
+            </xsl:apply-templates>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  wildcard match, ignore everything which has no explicit match
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="*"/>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  ignore all if tags except those for XPIDL or MIDL target
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="if">
+    <xsl:if test="(@target = 'xpidl') or (@target = 'midl')">
+        <xsl:apply-templates/>
+    </xsl:if>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  library match
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="interface">
+    <xsl:if test="not(@supportsErrorInfo='no')">
+        <xsl:call-template name="emitHeader">
+            <xsl:with-param name="iface" select="."/>
+        </xsl:call-template>
+
+        <xsl:call-template name="emitCode">
+            <xsl:with-param name="iface" select="."/>
+        </xsl:call-template>
+    </xsl:if>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  library match
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="library">
+    <xsl:apply-templates/>
+</xsl:template>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - -
+  root match
+ - - - - - - - - - - - - - - - - - - - - - - -->
+
+<xsl:template match="/idl">
+    <xsl:choose>
+        <xsl:when test="$filelistonly=''">
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:value-of select="concat($filelistonly, ' := \&#10;')"/>
+        </xsl:otherwise>
+    </xsl:choose>
+    <xsl:apply-templates/>
+    <xsl:choose>
+        <xsl:when test="$filelistonly=''">
+        </xsl:when>
+        <xsl:otherwise>
+            <xsl:text>
+</xsl:text>
+        </xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+<!-- vi: set tabstop=4 shiftwidth=4 expandtab: -->
Index: trunk/src/VBox/Main/include/MediumFormatImpl.h
===================================================================
--- trunk/src/VBox/Main/include/MediumFormatImpl.h	(revision 45517)
+++ trunk/src/VBox/Main/include/MediumFormatImpl.h	(revision 45518)
@@ -3,5 +3,5 @@
 /** @file
  *
- * VirtualBox COM class implementation
+ * MediumFormat COM class implementation
  */
 
@@ -18,12 +18,9 @@
  */
 
-#ifndef ____H_MEDIUMFORMAT
-#define ____H_MEDIUMFORMAT
+#ifndef MEDIUMFORMAT_IMPL_H_
+#define MEDIUMFORMAT_IMPL_H_
 
-#include "VirtualBoxBase.h"
+#include "MediumFormatWrap.h"
 
-#include <VBox/com/array.h>
-
-#include <list>
 
 struct VDBACKENDINFO;
@@ -39,6 +36,5 @@
  */
 class ATL_NO_VTABLE MediumFormat :
-    public VirtualBoxBase,
-    VBOX_SCRIPTABLE_IMPL(IMediumFormat)
+    public MediumFormatWrap
 {
 public:
@@ -53,29 +49,6 @@
     };
 
-    typedef std::list<Utf8Str>      StrList;
-    typedef std::list<DeviceType_T> DeviceTypeList;
-    typedef std::list<Property>     PropertyList;
-
-    struct Data
-    {
-        Data() : capabilities((MediumFormatCapabilities_T)0) {}
-
-        const Utf8Str        strId;
-        const Utf8Str        strName;
-        const StrList        llFileExtensions;
-        const DeviceTypeList llDeviceTypes;
-        const MediumFormatCapabilities_T capabilities;
-        const PropertyList   llProperties;
-    };
-
-    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(MediumFormat, IMediumFormat)
-
-    DECLARE_NOT_AGGREGATABLE(MediumFormat)
-
-    DECLARE_PROTECT_FINAL_CONSTRUCT()
-
-    BEGIN_COM_MAP(MediumFormat)
-        VBOX_DEFAULT_INTERFACE_ENTRIES(IMediumFormat)
-    END_COM_MAP()
+    typedef std::vector<Property> PropertyArray;
+    typedef std::vector<com::Utf8Str> StrArray;
 
     DECLARE_EMPTY_CTOR_DTOR(MediumFormat)
@@ -88,38 +61,52 @@
     void uninit();
 
-    // IMediumFormat properties
-    STDMETHOD(COMGETTER(Id))(BSTR *aId);
-    STDMETHOD(COMGETTER(Name))(BSTR *aName);
-    STDMETHOD(COMGETTER(Capabilities))(ComSafeArrayOut(MediumFormatCapabilities_T, aCaps));
-
-    // IMediumFormat methods
-    STDMETHOD(DescribeFileExtensions)(ComSafeArrayOut(BSTR, aFileExtensions),
-                                      ComSafeArrayOut(DeviceType_T, aDeviceTypes));
-    STDMETHOD(DescribeProperties)(ComSafeArrayOut(BSTR, aNames),
-                                  ComSafeArrayOut(BSTR, aDescriptions),
-                                  ComSafeArrayOut(DataType_T, aTypes),
-                                  ComSafeArrayOut(ULONG, aFlags),
-                                  ComSafeArrayOut(BSTR, aDefaults));
-
-    // public methods only for internal purposes
-
     // public methods for internal purposes only
     // (ensure there is a caller and a read lock before calling them!)
 
     /** Const, no need to lock */
-    const Utf8Str& getId() const { return m.strId; }
+    const Utf8Str &i_getId() const { return m.strId; }
     /** Const, no need to lock */
-    const StrList& getFileExtensions() const { return m.llFileExtensions; }
+    const StrArray &i_getFileExtensions() const { return m.maFileExtensions; }
     /** Const, no need to lock */
-    MediumFormatCapabilities_T getCapabilities() const { return m.capabilities; }
+    MediumFormatCapabilities_T i_getCapabilities() const { return m.capabilities; }
     /** Const, no need to lock */
-    const PropertyList& getProperties() const { return m.llProperties; }
+    const PropertyArray &i_getProperties() const { return m.maProperties; }
 
 private:
+
+    // wrapped IMediumFormat properties
+    HRESULT getId(com::Utf8Str &aId);
+    HRESULT getName(com::Utf8Str &aName);
+    HRESULT getCapabilities(std::vector<MediumFormatCapabilities_T> &aCapabilities);
+
+    // wrapped IMediumFormat methods
+    HRESULT describeFileExtensions(std::vector<com::Utf8Str> &aExtensions,
+                                   std::vector<DeviceType_T> &aTypes);
+    HRESULT describeProperties(std::vector<com::Utf8Str> &aNames,
+                               std::vector<com::Utf8Str> &aDescriptions,
+                               std::vector<DataType_T> &aTypes,
+                               std::vector<ULONG> &aFlags,
+                               std::vector<com::Utf8Str> &aDefaults);
+
+    // types
+    typedef std::vector<DeviceType_T> DeviceTypeArray;
+
+    // data
+    struct Data
+    {
+        Data() : capabilities((MediumFormatCapabilities_T)0) {}
+
+        const Utf8Str        strId;
+        const Utf8Str        strName;
+        const StrArray       maFileExtensions;
+        const DeviceTypeArray maDeviceTypes;
+        const MediumFormatCapabilities_T capabilities;
+        const PropertyArray  maProperties;
+    };
 
     Data m;
 };
 
-#endif // ____H_MEDIUMFORMAT
+#endif // MEDIUMFORMAT_IMPL_H_
 
 /* vi: set tabstop=4 shiftwidth=4 expandtab: */
Index: trunk/src/VBox/Main/include/Wrapper.h
===================================================================
--- trunk/src/VBox/Main/include/Wrapper.h	(revision 45518)
+++ trunk/src/VBox/Main/include/Wrapper.h	(revision 45518)
@@ -0,0 +1,481 @@
+/* $Id$ */
+
+/** @file
+ *
+ * VirtualBox COM: API wrapper helpers
+ */
+
+/*
+ * Copyright (C) 2012-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ____H_WRAPPER
+#define ____H_WRAPPER
+
+#include <vector>
+#include <VBox/com/ptr.h>
+#include <VBox/com/array.h>
+
+/**
+ * Checks that the given pointer to an output argument is valid and throws
+ * E_POINTER + extended error info otherwise.
+ * @param arg   Pointer argument.
+ */
+#define CheckComArgOutPointerValidThrow(arg) \
+    do { \
+        if (RT_UNLIKELY(!VALID_PTR(arg))) \
+            throw setError(E_POINTER, \
+                tr("Output argument %s points to invalid memory location (%p)"), \
+                #arg, (void *)(arg)); \
+    } while (0)
+
+
+class BSTROutConverter
+{
+public:
+    BSTROutConverter() : mDst(NULL)
+    {
+    }
+
+    BSTROutConverter(BSTR *aDst) : mDst(aDst)
+    {
+    }
+
+    ~BSTROutConverter()
+    {
+        if (mDst)
+            Bstr(mStr).detachTo(mDst);
+    }
+
+    com::Utf8Str &str()
+    {
+        return mStr;
+    }
+
+private:
+    com::Utf8Str mStr;
+    BSTR *mDst;
+};
+
+class BSTRInConverter
+{
+public:
+    BSTRInConverter() : mSrc()
+    {
+    }
+
+    BSTRInConverter(CBSTR aSrc) : mSrc(aSrc)
+    {
+    }
+
+    ~BSTRInConverter()
+    {
+    }
+
+    const com::Utf8Str &str()
+    {
+        return mSrc;
+    }
+
+private:
+    const com::Utf8Str mSrc;
+};
+
+class ArrayBSTROutConverter
+{
+public:
+    ArrayBSTROutConverter() :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(NULL),
+        mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+        mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ArrayBSTROutConverter(ComSafeArrayOut(BSTR, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(aDstSize),
+        mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+        mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ~ArrayBSTROutConverter()
+    {
+        if (mDst)
+        {
+            com::SafeArray<BSTR> outArray(mArray.size());
+            for (size_t i = 0; i < mArray.size(); i++)
+                Bstr(mArray[i]).detachTo(&outArray[i]);
+            outArray.detachTo(ComSafeArrayOutArg(mDst));
+        }
+    }
+
+    std::vector<com::Utf8Str> &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<com::Utf8Str> mArray;
+#ifdef VBOX_WITH_XPCOM
+    PRUint32 *mDstSize;
+    BSTR **mDst;
+#else // !VBOX_WITH_XPCOM
+    SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+class ArrayBSTRInConverter
+{
+public:
+    ArrayBSTRInConverter()
+    {
+    }
+
+    ArrayBSTRInConverter(ComSafeArrayIn(IN_BSTR, aSrc))
+    {
+        com::SafeArray<IN_BSTR> inArray(ComSafeArrayInArg(aSrc));
+        mArray.resize(inArray.size());
+        for (size_t i = 0; i < inArray.size(); i++)
+            mArray[i] = inArray[i];
+    }
+
+    ~ArrayBSTRInConverter()
+    {
+    }
+
+    const std::vector<com::Utf8Str> &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<com::Utf8Str> mArray;
+};
+
+class UuidOutConverter
+{
+public:
+    UuidOutConverter() : mDst(NULL)
+    {
+    }
+
+    UuidOutConverter(BSTR *aDst) : mDst(aDst)
+    {
+    }
+
+    ~UuidOutConverter()
+    {
+        if (mDst)
+            mUuid.toUtf16().detachTo(mDst);
+    }
+
+    com::Guid &uuid()
+    {
+        return mUuid;
+    }
+
+private:
+    com::Guid mUuid;
+    BSTR *mDst;
+};
+
+class UuidInConverter
+{
+public:
+    UuidInConverter() : mSrc()
+    {
+    }
+
+    UuidInConverter(CBSTR aSrc) : mSrc(aSrc)
+    {
+    }
+
+    ~UuidInConverter()
+    {
+    }
+
+    const com::Guid &uuid()
+    {
+        return mSrc;
+    }
+
+private:
+    const com::Guid mSrc;
+};
+
+class ArrayUuidOutConverter
+{
+public:
+    ArrayUuidOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(NULL),
+        mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+        mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ArrayUuidOutConverter(ComSafeArrayOut(BSTR, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(aDstSize),
+        mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+        mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ~ArrayUuidOutConverter()
+    {
+        if (mDst)
+        {
+            com::SafeArray<BSTR> outArray(mArray.size());
+            for (size_t i = 0; i < mArray.size(); i++)
+                mArray[i].toUtf16().detachTo(&outArray[i]);
+            outArray.detachTo(ComSafeArrayOutArg(mDst));
+        }
+    }
+
+    std::vector<com::Guid> &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<com::Guid> mArray;
+#ifdef VBOX_WITH_XPCOM
+    PRUint32 *mDstSize;
+    BSTR **mDst;
+#else // !VBOX_WITH_XPCOM
+    SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <class A>
+class ComTypeOutConverter
+{
+public:
+    ComTypeOutConverter() : mDst(NULL)
+    {
+    }
+
+    ComTypeOutConverter(A **aDst) : mDst(aDst)
+    {
+    }
+
+    ~ComTypeOutConverter()
+    {
+        if (mDst)
+            mPtr.queryInterfaceTo(mDst);
+    }
+
+    ComPtr<A> &ptr()
+    {
+        return mPtr;
+    }
+
+private:
+    ComPtr<A> mPtr;
+    A **mDst;
+};
+
+template <class A>
+class ComTypeInConverter
+{
+public:
+    ComTypeInConverter() : mSrc(NULL)
+    {
+    }
+
+    ComTypeInConverter(A *aSrc) : mSrc(mSrc)
+    {
+    }
+
+    ~ComTypeInConverter()
+    {
+    }
+
+    const ComPtr<A> &ptr()
+    {
+        return mSrc;
+    }
+
+private:
+    const ComPtr<A> mSrc;
+};
+
+template <class A>
+class ArrayComTypeOutConverter
+{
+public:
+    ArrayComTypeOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(NULL),
+        mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+        mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ArrayComTypeOutConverter(ComSafeArrayOut(A *, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(aDstSize),
+        mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+        mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ~ArrayComTypeOutConverter()
+    {
+        if (mDst)
+        {
+            com::SafeIfaceArray<A> outArray(mArray.size());
+            for (size_t i = 0; i < mArray.size(); i++)
+                outArray[i] = mArray[i];
+            outArray.detachTo(ComSafeArrayOutArg(mDst));
+        }
+    }
+
+    std::vector<ComPtr<A> > &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<ComPtr<A> > mArray;
+#ifdef VBOX_WITH_XPCOM
+    PRUint32 *mDstSize;
+    A ***mDst;
+#else // !VBOX_WITH_XPCOM
+    SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <class A>
+class ArrayComTypeInConverter
+{
+public:
+    ArrayComTypeInConverter()
+    {
+    }
+
+    ArrayComTypeInConverter(ComSafeArrayIn(A *, aSrc))
+    {
+        com::SafeIfaceArray<A> inArray(ComSafeArrayInArg(aSrc));
+        mArray.resize(inArray.size());
+        for (size_t i = 0; i < inArray.size(); i++)
+            mArray[i] = inArray[i];
+    }
+
+    ~ArrayComTypeInConverter()
+    {
+    }
+
+    const std::vector<ComPtr<A> > &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<ComPtr<A> > mArray;
+};
+
+template <typename A>
+class ArrayOutConverter
+{
+public:
+    ArrayOutConverter() :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(NULL),
+        mDst(NULL)
+#else // !VBOX_WITH_XPCOM
+        mDst(NULL)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ArrayOutConverter(ComSafeArrayOut(A, aDst)) :
+#ifdef VBOX_WITH_XPCOM
+        mDstSize(aDstSize),
+        mDst(aDst)
+#else // !VBOX_WITH_XPCOM
+        mDst(aDst)
+#endif // !VBOX_WITH_XPCOM
+    {
+    }
+
+    ~ArrayOutConverter()
+    {
+        if (mDst)
+        {
+            com::SafeArray<A> outArray(mArray.size());
+            for (size_t i = 0; i < mArray.size(); i++)
+                outArray[i] = mArray[i];
+            outArray.detachTo(ComSafeArrayOutArg(mDst));
+        }
+    }
+
+    std::vector<A> &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<A> mArray;
+#ifdef VBOX_WITH_XPCOM
+    PRUint32 *mDstSize;
+    A **mDst;
+#else // !VBOX_WITH_XPCOM
+    SAFEARRAY **mDst;
+#endif // !VBOX_WITH_XPCOM
+};
+
+template <typename A>
+class ArrayInConverter
+{
+public:
+    ArrayInConverter()
+    {
+    }
+
+    ArrayInConverter(ComSafeArrayIn(A, aSrc))
+    {
+        com::SafeArray<A> inArray(ComSafeArrayInArg(aSrc));
+        mArray.resize(inArray.size());
+        for (size_t i = 0; i < inArray.size(); i++)
+            mArray[i] = inArray[i];
+    }
+
+    ~ArrayInConverter()
+    {
+    }
+
+    const std::vector<A> &array()
+    {
+        return mArray;
+    }
+
+private:
+    std::vector<A> mArray;
+};
+
+#endif // ____H_WRAPPER
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Index: trunk/src/VBox/Main/src-server/MediumFormatImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/MediumFormatImpl.cpp	(revision 45517)
+++ trunk/src/VBox/Main/src-server/MediumFormatImpl.cpp	(revision 45518)
@@ -2,5 +2,5 @@
 /** @file
  *
- * VirtualBox COM class implementation
+ * MediumFormat COM class implementation
  */
 
@@ -76,5 +76,5 @@
             DeviceType_T devType;
 
-            unconst(m.llFileExtensions).push_back(papExtension->pszExtension);
+            unconst(m.maFileExtensions).push_back(papExtension->pszExtension);
 
             switch(papExtension->enmType)
@@ -94,5 +94,5 @@
             }
 
-            unconst(m.llDeviceTypes).push_back(devType);
+            unconst(m.maDeviceTypes).push_back(devType);
             ++papExtension;
         }
@@ -157,5 +157,5 @@
                                     flags,
                                     defaultValue };
-            unconst(m.llProperties).push_back(prop);
+            unconst(m.maProperties).push_back(prop);
             ++pa;
         }
@@ -181,7 +181,7 @@
         return;
 
-    unconst(m.llProperties).clear();
-    unconst(m.llFileExtensions).clear();
-    unconst(m.llDeviceTypes).clear();
+    unconst(m.maProperties).clear();
+    unconst(m.maFileExtensions).clear();
+    unconst(m.maDeviceTypes).clear();
     unconst(m.capabilities) = (MediumFormatCapabilities_T)0;
     unconst(m.strName).setNull();
@@ -192,122 +192,34 @@
 /////////////////////////////////////////////////////////////////////////////
 
-STDMETHODIMP MediumFormat::COMGETTER(Id)(BSTR *aId)
-{
-    CheckComArgOutPointerValid(aId);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    /* this is const, no need to lock */
-    m.strId.cloneTo(aId);
-
-    return S_OK;
-}
-
-STDMETHODIMP MediumFormat::COMGETTER(Name)(BSTR *aName)
-{
-    CheckComArgOutPointerValid(aName);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    /* this is const, no need to lock */
-    m.strName.cloneTo(aName);
-
-    return S_OK;
-}
-
-STDMETHODIMP MediumFormat::COMGETTER(Capabilities)(ComSafeArrayOut(MediumFormatCapabilities_T, aCaps))
-{
-    CheckComArgOutSafeArrayPointerValid(aCaps);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    SafeArray<MediumFormatCapabilities_T> capabilities(sizeof(MediumFormatCapabilities_T)*8);
-
-    for (ULONG i = 0; i < capabilities.size(); ++i)
-    {
-        ULONG temp = m.capabilities;
-        temp &= 1<<i;
-        capabilities [i] = (MediumFormatCapabilities_T)temp;
-    }
-
-    capabilities.detachTo(ComSafeArrayOutArg(aCaps));
-
-    return S_OK;
-}
-
-STDMETHODIMP MediumFormat::DescribeFileExtensions(ComSafeArrayOut(BSTR, aFileExtensions),
-                                                  ComSafeArrayOut(DeviceType_T, aDeviceTypes))
-{
-    CheckComArgOutSafeArrayPointerValid(aFileExtensions);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    /* this is const, no need to lock */
-    com::SafeArray<BSTR> fileExtentions(m.llFileExtensions.size());
-    int i = 0;
-    for (StrList::const_iterator it = m.llFileExtensions.begin();
-         it != m.llFileExtensions.end();
-         ++it, ++i)
-        (*it).cloneTo(&fileExtentions[i]);
-    fileExtentions.detachTo(ComSafeArrayOutArg(aFileExtensions));
-
-    com::SafeArray<DeviceType_T> deviceTypes(m.llDeviceTypes.size());
-    i = 0;
-    for (DeviceTypeList::const_iterator it = m.llDeviceTypes.begin();
-         it != m.llDeviceTypes.end();
-         ++it, ++i)
-        deviceTypes[i] = (*it);
-    deviceTypes.detachTo(ComSafeArrayOutArg(aDeviceTypes));
-
-    return S_OK;
-}
-
-STDMETHODIMP MediumFormat::DescribeProperties(ComSafeArrayOut(BSTR, aNames),
-                                              ComSafeArrayOut(BSTR, aDescriptions),
-                                              ComSafeArrayOut(DataType_T, aTypes),
-                                              ComSafeArrayOut(ULONG, aFlags),
-                                              ComSafeArrayOut(BSTR, aDefaults))
-{
-    CheckComArgOutSafeArrayPointerValid(aNames);
-    CheckComArgOutSafeArrayPointerValid(aDescriptions);
-    CheckComArgOutSafeArrayPointerValid(aTypes);
-    CheckComArgOutSafeArrayPointerValid(aFlags);
-    CheckComArgOutSafeArrayPointerValid(aDefaults);
-
-    AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    /* this is const, no need to lock */
-    size_t c = m.llProperties.size();
-    com::SafeArray<BSTR>        propertyNames(c);
-    com::SafeArray<BSTR>        propertyDescriptions(c);
-    com::SafeArray<DataType_T>  propertyTypes(c);
-    com::SafeArray<ULONG>       propertyFlags(c);
-    com::SafeArray<BSTR>        propertyDefaults(c);
-
-    int i = 0;
-    for (PropertyList::const_iterator it = m.llProperties.begin();
-         it != m.llProperties.end();
-         ++it, ++i)
-    {
-        const Property &prop = (*it);
-        prop.strName.cloneTo(&propertyNames[i]);
-        prop.strDescription.cloneTo(&propertyDescriptions[i]);
-        propertyTypes[i] = prop.type;
-        propertyFlags[i] = prop.flags;
-        prop.strDefaultValue.cloneTo(&propertyDefaults[i]);
-    }
-
-    propertyNames.detachTo(ComSafeArrayOutArg(aNames));
-    propertyDescriptions.detachTo(ComSafeArrayOutArg(aDescriptions));
-    propertyTypes.detachTo(ComSafeArrayOutArg(aTypes));
-    propertyFlags.detachTo(ComSafeArrayOutArg(aFlags));
-    propertyDefaults.detachTo(ComSafeArrayOutArg(aDefaults));
+HRESULT MediumFormat::getId(com::Utf8Str &aId)
+{
+    /* this is const, no need to lock */
+    aId = m.strId;
+
+    return S_OK;
+}
+
+HRESULT MediumFormat::getName(com::Utf8Str &aName)
+{
+    /* this is const, no need to lock */
+    aName = m.strName;
+
+    return S_OK;
+}
+
+HRESULT MediumFormat::getCapabilities(std::vector<MediumFormatCapabilities_T> &aCapabilities)
+{
+    /* m.capabilities is const, no need to lock */
+
+    aCapabilities.resize(sizeof(MediumFormatCapabilities_T) * 8);
+    size_t cCapabilities = 0;
+    for (size_t i = 0; i < aCapabilities.size(); i++)
+    {
+        uint64_t tmp = m.capabilities;
+        tmp &= 1ULL << i;
+        if (tmp)
+            aCapabilities[cCapabilities] = (MediumFormatCapabilities_T)tmp;
+    }
+    aCapabilities.resize(RT_MIN(cCapabilities, 1));
 
     return S_OK;
@@ -317,4 +229,40 @@
 /////////////////////////////////////////////////////////////////////////////
 
+HRESULT MediumFormat::describeFileExtensions(std::vector<com::Utf8Str> &aExtensions,
+                                             std::vector<DeviceType_T> &aTypes)
+{
+    /* this is const, no need to lock */
+    aExtensions = m.maFileExtensions;
+    aTypes = m.maDeviceTypes;
+
+    return S_OK;
+}
+
+HRESULT MediumFormat::describeProperties(std::vector<com::Utf8Str> &aNames,
+                                         std::vector<com::Utf8Str> &aDescriptions,
+                                         std::vector<DataType_T> &aTypes,
+                                         std::vector<ULONG> &aFlags,
+                                         std::vector<com::Utf8Str> &aDefaults)
+{
+    /* this is const, no need to lock */
+    size_t c = m.maProperties.size();
+    aNames.resize(c);
+    aDescriptions.resize(c);
+    aTypes.resize(c);
+    aFlags.resize(c);
+    aDefaults.resize(c);
+    for (size_t i = 0; i < c; i++)
+    {
+        const Property &prop = m.maProperties[i];
+        aNames[i] = prop.strName;
+        aDescriptions[i] = prop.strDescription;
+        aTypes[i] = prop.type;
+        aFlags[i] = prop.flags;
+        aDefaults[i] = prop.strDefaultValue;
+    }
+
+    return S_OK;
+}
+
 // public methods only for internal purposes
 /////////////////////////////////////////////////////////////////////////////
Index: trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 45517)
+++ trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 45518)
@@ -959,5 +959,5 @@
     if (FAILED(rc)) return rc;
 
-    if (!(m->formatObj->getCapabilities() & (   MediumFormatCapabilities_CreateFixed
+    if (!(m->formatObj->i_getCapabilities() & (   MediumFormatCapabilities_CreateFixed
                                               | MediumFormatCapabilities_CreateDynamic))
        )
@@ -1240,5 +1240,5 @@
 
     Utf8Str strFull;
-    if (m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+    if (m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File)
     {
         // compose full path of the medium, if it's not fully qualified...
@@ -2517,5 +2517,5 @@
 
         if (    !(mediumVariantFlags & MediumVariant_Fixed)
-            &&  !(m->formatObj->getCapabilities() & MediumFormatCapabilities_CreateDynamic))
+            &&  !(m->formatObj->i_getCapabilities() & MediumFormatCapabilities_CreateDynamic))
             throw setError(VBOX_E_NOT_SUPPORTED,
                            tr("Medium format '%s' does not support dynamic storage creation"),
@@ -2523,5 +2523,5 @@
 
         if (    (mediumVariantFlags & MediumVariant_Fixed)
-            &&  !(m->formatObj->getCapabilities() & MediumFormatCapabilities_CreateDynamic))
+            &&  !(m->formatObj->i_getCapabilities() & MediumFormatCapabilities_CreateDynamic))
             throw setError(VBOX_E_NOT_SUPPORTED,
                            tr("Medium format '%s' does not support fixed storage creation"),
@@ -3194,5 +3194,5 @@
 {
     if (    m->formatObj
-         && (m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+         && (m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File)
        )
         return true;
@@ -4137,5 +4137,5 @@
 
     /* check that our own format supports diffs */
-    if (!(m->formatObj->getCapabilities() & MediumFormatCapabilities_Differencing))
+    if (!(m->formatObj->i_getCapabilities() & MediumFormatCapabilities_Differencing))
     {
         /* use the default format if not */
@@ -4270,5 +4270,5 @@
         LogFlowThisFunc(("aWait=%RTbool locationFull=%s\n", aWait, getLocationFull().c_str() ));
 
-        if (    !(m->formatObj->getCapabilities() & (   MediumFormatCapabilities_CreateDynamic
+        if (    !(m->formatObj->i_getCapabilities() & (   MediumFormatCapabilities_CreateDynamic
                                                       | MediumFormatCapabilities_CreateFixed)))
             throw setError(VBOX_E_NOT_SUPPORTED,
@@ -5676,5 +5676,5 @@
             }
 
-            if (formatObj->getCapabilities() & MediumFormatCapabilities_Uuid)
+            if (formatObj->i_getCapabilities() & MediumFormatCapabilities_Uuid)
             {
                 /* Modify the UUIDs if necessary. The associated fields are
@@ -6204,5 +6204,5 @@
 
     if (   isImport
-        || (   (m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+        || (   (m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File)
             && !m->hostDrive))
     {
@@ -6214,5 +6214,5 @@
         {
             /* must be a file (formatObj must be already known) */
-            Assert(m->formatObj->getCapabilities() & MediumFormatCapabilities_File);
+            Assert(m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File);
 
             if (RTPathFilename(aLocation.c_str()) == NULL)
@@ -6222,9 +6222,9 @@
                  * this */
 
-                ComAssertMsgRet(!m->formatObj->getFileExtensions().empty(),
+                ComAssertMsgRet(!m->formatObj->i_getFileExtensions().empty(),
                                 ("Must be at least one extension if it is MediumFormatCapabilities_File\n"),
                                 E_FAIL);
 
-                Utf8Str strExt = m->formatObj->getFileExtensions().front();
+                Utf8Str strExt = m->formatObj->i_getFileExtensions().front();
                 ComAssertMsgRet(!strExt.isEmpty(),
                                 ("Default extension must not be empty\n"),
@@ -6240,5 +6240,5 @@
         // we must always have full paths now (if it refers to a file)
         if (   (   m->formatObj.isNull()
-                || m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+                || m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File)
             && !RTPathStartsWithRoot(locationFull.c_str()))
             return setError(VBOX_E_FILE_ERROR,
@@ -6326,5 +6326,5 @@
 
         /* is it still a file? */
-        if (    (m->formatObj->getCapabilities() & MediumFormatCapabilities_File)
+        if (    (m->formatObj->i_getCapabilities() & MediumFormatCapabilities_File)
              && (m->state == MediumState_NotCreated)
            )
@@ -6374,6 +6374,6 @@
         Assert(m->mapProperties.empty());
 
-        for (MediumFormat::PropertyList::const_iterator it = m->formatObj->getProperties().begin();
-             it != m->formatObj->getProperties().end();
+        for (MediumFormat::PropertyArray::const_iterator it = m->formatObj->i_getProperties().begin();
+             it != m->formatObj->i_getProperties().end();
              ++it)
         {
@@ -6764,5 +6764,5 @@
         Utf8Str format(m->strFormat);
         Utf8Str location(m->strLocationFull);
-        uint64_t capabilities = m->formatObj->getCapabilities();
+        uint64_t capabilities = m->formatObj->i_getCapabilities();
         ComAssertThrow(capabilities & (  MediumFormatCapabilities_CreateFixed
                                        | MediumFormatCapabilities_CreateDynamic), E_FAIL);
@@ -6904,5 +6904,5 @@
         Utf8Str targetFormat(pTarget->m->strFormat);
         Utf8Str targetLocation(pTarget->m->strLocationFull);
-        uint64_t capabilities = pTarget->m->formatObj->getCapabilities();
+        uint64_t capabilities = pTarget->m->formatObj->i_getCapabilities();
         ComAssertThrow(capabilities & MediumFormatCapabilities_CreateDynamic, E_FAIL);
 
@@ -7442,5 +7442,5 @@
             Utf8Str targetFormat(pTarget->m->strFormat);
             Utf8Str targetLocation(pTarget->m->strLocationFull);
-            uint64_t capabilities = pTarget->m->formatObj->getCapabilities();
+            uint64_t capabilities = pTarget->m->formatObj->i_getCapabilities();
 
             Assert(   pTarget->m->state == MediumState_Creating
@@ -8125,7 +8125,7 @@
             }
 
-            Utf8Str targetFormat(task.mFormat->getId());
+            Utf8Str targetFormat(task.mFormat->i_getId());
             Utf8Str targetLocation(task.mFilename);
-            uint64_t capabilities = task.mFormat->getCapabilities();
+            uint64_t capabilities = task.mFormat->i_getCapabilities();
 
             Assert(m->state == MediumState_LockedRead);
@@ -8238,5 +8238,5 @@
             /* Open source medium. */
             vrc = VDOpen(hdd,
-                         task.mFormat->getId().c_str(),
+                         task.mFormat->i_getId().c_str(),
                          task.mFilename.c_str(),
                          VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SEQUENTIAL | m->uOpenFlagsDef,
@@ -8250,5 +8250,5 @@
             Utf8Str targetFormat(m->strFormat);
             Utf8Str targetLocation(m->strLocationFull);
-            uint64_t capabilities = task.mFormat->getCapabilities();
+            uint64_t capabilities = task.mFormat->i_getCapabilities();
 
             Assert(   m->state == MediumState_Creating
Index: trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp	(revision 45517)
+++ trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp	(revision 45518)
@@ -1106,5 +1106,5 @@
         /* MediumFormat is all const, no need to lock */
 
-        if ((*it)->getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
+        if ((*it)->i_getId().compare(aFormat, Utf8Str::CaseInsensitive) == 0)
         {
             format = *it;
@@ -1139,6 +1139,6 @@
     {
         /* MediumFormat is all const, no need to lock */
-        MediumFormat::StrList aFileList = (*it)->getFileExtensions();
-        for (MediumFormat::StrList::const_iterator it1 = aFileList.begin();
+        MediumFormat::StrArray aFileList = (*it)->i_getFileExtensions();
+        for (MediumFormat::StrArray::const_iterator it1 = aFileList.begin();
              it1 != aFileList.end();
              ++it1)
Index: trunk/src/VBox/Main/src-server/xpcom/server.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 45517)
+++ trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 45518)
@@ -128,7 +128,4 @@
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Medium, IMedium)
 
-NS_DECL_CLASSINFO(MediumFormat)
-NS_IMPL_THREADSAFE_ISUPPORTS1_CI(MediumFormat, IMediumFormat)
-
 NS_DECL_CLASSINFO(MediumAttachment)
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(MediumAttachment, IMediumAttachment)
