Index: /trunk/include/VBox/com/Guid.h
===================================================================
--- /trunk/include/VBox/com/Guid.h	(revision 26752)
+++ /trunk/include/VBox/com/Guid.h	(revision 26753)
@@ -96,11 +96,11 @@
     Guid(const Bstr &that)
     {
-        ::RTUuidClear (&uuid);
-        if (!that.isNull())
+        ::RTUuidClear(&uuid);
+        if (!that.isEmpty())
            ::RTUuidFromUtf16(&uuid, that.raw());
         refresh();
     }
 
-    Guid &operator=(const Guid &that)
+    Guid& operator=(const Guid &that)
     {
         ::memcpy(&uuid, &that.uuid, sizeof (RTUUID));
@@ -108,5 +108,5 @@
         return *this;
     }
-    Guid &operator=(const GUID &guid)
+    Guid& operator=(const GUID &guid)
     {
         ::memcpy(&uuid, &guid, sizeof (GUID));
@@ -114,5 +114,5 @@
         return *this;
     }
-    Guid &operator=(const RTUUID &guid)
+    Guid& operator=(const RTUUID &guid)
     {
         ::memcpy(&uuid, &guid, sizeof (RTUUID));
@@ -120,5 +120,5 @@
         return *this;
     }
-    Guid &operator=(const char *str)
+    Guid& operator=(const char *str)
     {
         ::RTUuidFromStr(&uuid, str);
@@ -145,5 +145,5 @@
     }
 
-    Bstr toUtf16 () const
+    Bstr toUtf16() const
     {
         if (isEmpty())
Index: /trunk/include/VBox/com/string.h
===================================================================
--- /trunk/include/VBox/com/string.h	(revision 26752)
+++ /trunk/include/VBox/com/string.h	(revision 26753)
@@ -49,5 +49,4 @@
 #include "VBox/com/assert.h"
 
-#include <iprt/cpp/utils.h>
 #include <iprt/alloc.h>
 #include <iprt/cpp/ministring.h>
@@ -58,16 +57,39 @@
 class Utf8Str;
 
+// global constant in glue/string.cpp that represents an empty BSTR
+extern const BSTR g_bstrEmpty;
+
 /**
- *  Helper class that represents the |BSTR| type and hides platform-specific
- *  implementation details.
- *
- *  This class uses COM/XPCOM-provided memory management routines to allocate
- *  and free string buffers. This makes it possible to:
- *  - use it as a type of member variables of COM/XPCOM components and pass
- *    their values to callers through component methods' output parameters
- *    using the #cloneTo() operation;
- *  - adopt (take ownership of) string buffers returned in output parameters
- *    of COM methods using the #asOutParam() operation and correctly free them
- *    afterwards.
+ *  String class used universally in Main for COM-style Utf-16 strings.
+ *  Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
+ *  back and forth since most of VirtualBox and our libraries use UTF-8.
+ *
+ *  To make things more obscure, on Windows, a COM-style BSTR is not just a
+ *  pointer to a null-terminated wide character array, but the four bytes
+ *  (32 bits) BEFORE the memory that the pointer points to are a length
+ *  DWORD. One must therefore avoid pointer arithmetic and always use
+ *  SysAllocString and the like to deal with BSTR pointers, which manage
+ *  that DWORD correctly.
+ *
+ *  For platforms other than Windows, we provide our own versions of the
+ *  Sys* functions in Main/xpcom/helpers.cpp which do NOT use length
+ *  prefixes though to be compatible with how XPCOM allocates string
+ *  parameters to public functions.
+ *
+ *  The Bstr class hides all this handling behind a std::string-like interface
+ *  and also provides automatic conversions to MiniString and Utf8Str instances.
+ *
+ *  The one advantage of using the SysString* routines is that this makes it
+ *  possible to use it as a type of member variables of COM/XPCOM components
+ *  and pass their values to callers through component methods' output parameters
+ *  using the #cloneTo() operation. Also, the class can adopt (take ownership of)
+ *  string buffers returned in output parameters of COM methods using the
+ *  #asOutParam() operation and correctly free them afterwards.
+ *
+ *  Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
+ *  between NULL strings and empty strings. In other words, Bstr("") and
+ *  Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
+ *  reports a zero length and zero allocated bytes for both, and returns an
+ *  empty C wide string from raw().
  */
 class Bstr
@@ -75,143 +97,167 @@
 public:
 
-    typedef BSTR String;
-    typedef CBSTR ConstString;
-
-    Bstr() : bstr(NULL) {}
-
-    Bstr(const Bstr &that) : bstr(NULL) { raw_copy(bstr, that.bstr); }
-    Bstr(CBSTR that) : bstr(NULL) { raw_copy(bstr, that); }
+    Bstr()
+        : m_bstr(NULL)
+    { }
+
+    Bstr(const Bstr &that)
+    {
+        copyFrom((const OLECHAR *)that.m_bstr);
+    }
+
+    Bstr(CBSTR that)
+    {
+        copyFrom((const OLECHAR *)that);
+    }
 
 #if defined (VBOX_WITH_XPCOM)
-    Bstr(const wchar_t *that) : bstr(NULL)
+    Bstr(const wchar_t *that)
     {
         AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
-        raw_copy(bstr, (CBSTR)that);
-    }
-#endif
-
-    Bstr(const iprt::MiniString &that);
-    Bstr(const char *that);
-
-    /** Shortcut that calls #alloc(aSize) right after object creation. */
-    Bstr(size_t aSize) : bstr(NULL) { alloc(aSize); }
-
-    ~Bstr() { setNull(); }
-
-    Bstr &operator=(const Bstr &that) { safe_assign(that.bstr); return *this; }
-    Bstr &operator=(CBSTR that) { safe_assign(that); return *this; }
-
-    Bstr &operator=(const Utf8Str &that);
-    Bstr &operator=(const char *that);
-
-    Bstr &setNull()
-    {
-        if (bstr)
-        {
-            ::SysFreeString(bstr);
-            bstr = NULL;
-        }
+        copyFrom((const OLECHAR *)that);
+    }
+#endif
+
+    Bstr(const iprt::MiniString &that)
+    {
+        copyFrom(that.raw());
+    }
+
+    Bstr(const char *that)
+    {
+        copyFrom(that);
+    }
+
+    ~Bstr()
+    {
+        setNull();
+    }
+
+    Bstr& operator=(const Bstr &that)
+    {
+        cleanup();
+        copyFrom((const OLECHAR *)that.m_bstr);
         return *this;
     }
 
-    Bstr &setNullIfEmpty()
-    {
-        if (bstr && *bstr == 0)
-        {
-            ::SysFreeString(bstr);
-            bstr = NULL;
-        }
+    Bstr& operator=(CBSTR that)
+    {
+        cleanup();
+        copyFrom((const OLECHAR *)that);
         return *this;
     }
 
-    /**
-     *  Allocates memory for a string capable to store \a aSize - 1 characters;
-     *  in other words, aSize includes the terminating zero character. If \a aSize
-     *  is zero, or if a memory allocation error occurs, this object will become null.
-     */
-    Bstr &alloc(size_t aSize)
-    {
-        setNull();
-        if (aSize)
-        {
-            unsigned int size = (unsigned int) aSize; Assert(size == aSize);
-            bstr = ::SysAllocStringLen(NULL, size - 1);
-            if (bstr)
-                bstr[0] = 0;
-        }
+#if defined (VBOX_WITH_XPCOM)
+    Bstr& operator=(const wchar_t *that)
+    {
+        cleanup();
+        copyFrom((const OLECHAR *)that);
         return *this;
     }
-
-    int compare(CBSTR str) const
-    {
-        return ::RTUtf16Cmp((PRTUTF16) bstr, (PRTUTF16) str);
+#endif
+
+    Bstr& setNull()
+    {
+        cleanup();
+        return *this;
+    }
+
+    /** Case sensitivity selector. */
+    enum CaseSensitivity
+    {
+        CaseSensitive,
+        CaseInsensitive
+    };
+
+    /**
+     * Compares the member string to str.
+     * @param str
+     * @param cs Whether comparison should be case-sensitive.
+     * @return
+     */
+    int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
+    {
+        if (cs == CaseSensitive)
+            return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
+        return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
     }
 
     int compare(BSTR str) const
     {
-        return ::RTUtf16Cmp((PRTUTF16) bstr, (PRTUTF16) str);
-    }
-
-    bool operator==(const Bstr &that) const { return !compare(that.bstr); }
-    bool operator!=(const Bstr &that) const { return !!compare(that.bstr); }
+        return compare((CBSTR)str);
+    }
+
+    bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
+    bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
     bool operator==(CBSTR that) const { return !compare(that); }
     bool operator==(BSTR that) const { return !compare(that); }
 
-#if defined (VBOX_WITH_XPCOM)
-    bool operator!=(const wchar_t *that) const
-    {
-        AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
-        return !!compare((CBSTR) that);
-    }
-    bool operator==(const wchar_t *that) const
-    {
-        AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
-        return !compare((CBSTR) that);
-    }
-#endif
-
     bool operator!=(CBSTR that) const { return !!compare(that); }
     bool operator!=(BSTR that) const { return !!compare(that); }
-    bool operator<(const Bstr &that) const { return compare(that.bstr) < 0; }
+    bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
     bool operator<(CBSTR that) const { return compare(that) < 0; }
     bool operator<(BSTR that) const { return compare(that) < 0; }
-#if defined (VBOX_WITH_XPCOM)
-    bool operator<(const wchar_t *that) const
-    {
-        AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
-        return compare((CBSTR) that) < 0;
-    }
-#endif
-
-    int compareIgnoreCase(CBSTR str) const
-    {
-        return ::RTUtf16LocaleICmp(bstr, str);
-    }
-
-    bool isNull() const { return bstr == NULL; }
-    operator bool() const { return !isNull(); }
-
-    bool isEmpty() const { return isNull() || *bstr == 0; }
-
-    size_t length() const { return isNull() ? 0 : ::RTUtf16Len((PRTUTF16) bstr); }
-
-    /** Intended to to pass instances as |CBSTR| input parameters to methods. */
-    operator CBSTR() const { return bstr; }
-
-    /**
-     * Intended to to pass instances as |BSTR| input parameters to methods.
-     * Note that we have to provide this mutable BSTR operator since in MS COM
-     * input BSTR parameters of interface methods are not const.
-     */
-    operator BSTR() { return bstr; }
-
-    /**
-     *  The same as operator CBSTR(), but for situations where the compiler
-     *  cannot typecast implicitly (for example, in printf() argument list).
-     */
-    CBSTR raw() const { return bstr; }
+
+    /**
+     * Returns true if the member string has no length.
+     * This is true for instances created from both NULL and "" input strings.
+     *
+     * @note Always use this method to check if an instance is empty. Do not
+     * use length() because that may need to run through the entire string
+     * (Bstr does not cache string lengths). Also do not use operator bool();
+     * for one, MSVC is really annoying with its thinking that that is ambiguous,
+     * and even though operator bool() is protected with Bstr, at least gcc uses
+     * operator CBSTR() when a construct like "if (string)" is encountered, which
+     * is always true now since it raw() never returns an empty string. Again,
+     * always use isEmpty() even though if (string) may compile!
+     */
+    bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
+
+    size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
+
+    /**
+     * Returns true if the member string is not empty. I'd like to make this
+     * private but since we require operator BSTR() it's futile anyway because
+     * the compiler will then (wrongly) use that one instead. Also if this is
+     * private the odd WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP macro below
+     * will fail on Windows.
+     */
+    operator bool() const
+    {
+        return m_bstr != NULL;
+    }
+
+    /**
+     *  Returns a pointer to the raw member UTF-16 string. If the member string is empty,
+     *  returns a pointer to a global variable containing an empty BSTR with a proper zero
+     *  length prefix so that Windows is happy.
+     */
+    CBSTR raw() const
+    {
+        if (m_bstr)
+            return m_bstr;
+
+        return g_bstrEmpty;
+    }
+
+    /**
+     * Convenience operator so that Bstr's can be passed to CBSTR input parameters
+     * of COM methods.
+     */
+    operator CBSTR() const { return raw(); }
+
+    /**
+     * Convenience operator so that Bstr's can be passed to CBSTR input parameters
+     * of COM methods. Unfortunately this is required for Windows since with
+     * MSCOM, input BSTR parameters of interface methods are not const.
+     */
+    operator BSTR() { return (BSTR)raw(); }
 
     /**
      *  Returns a non-const raw pointer that allows to modify the string directly.
+     *  As opposed to raw(), this DOES return NULL if the member string is empty
+     *  because we cannot return a mutable pointer to the global variable with the
+     *  empty string.
+     *
      *  @warning
      *      Be sure not to modify data beyond the allocated memory! The
@@ -219,5 +265,5 @@
      *      bytes after creation and after every assignment operation.
      */
-    BSTR mutableRaw() { return bstr; }
+    BSTR mutableRaw() { return m_bstr; }
 
     /**
@@ -225,13 +271,18 @@
      *  within the interface method. Transfers the ownership of the duplicated
      *  string to the caller.
-     */
-    const Bstr &cloneTo(BSTR *pstr) const
+     *
+     *  If the member string is empty, this allocates an empty BSTR in *pstr
+     *  (i.e. makes it point to a new buffer with a null byte).
+     */
+    void cloneTo(BSTR *pstr) const
     {
         if (pstr)
         {
-            *pstr = NULL;
-            raw_copy(*pstr, bstr);
+            *pstr = ::SysAllocString((const OLECHAR *)raw());       // raw() returns a pointer to "" if empty
+#ifdef RT_EXCEPTIONS_ENABLED
+            if (!*pstr)
+                throw std::bad_alloc();
+#endif
         }
-        return *this;
     }
 
@@ -243,18 +294,23 @@
      *  As opposed to cloneTo(), this method doesn't create a copy of the
      *  string.
-     */
-    Bstr &detachTo(BSTR *pstr)
-    {
-        *pstr = bstr;
-        bstr = NULL;
-        return *this;
-    }
-
-    /**
-     *  Intended to assign copies of instances to |char *| out parameters from
-     *  within the interface method. Transfers the ownership of the duplicated
-     *  string to the caller.
-     */
-    const Bstr &cloneTo(char **pstr) const;
+     *
+     *  If the member string is empty, this allocates an empty BSTR in *pstr
+     *  (i.e. makes it point to a new buffer with a null byte).
+     */
+    void detachTo(BSTR *pstr)
+    {
+        if (m_bstr)
+            *pstr = m_bstr;
+        else
+        {
+            // allocate null BSTR
+            *pstr = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
+#ifdef RT_EXCEPTIONS_ENABLED
+            if (!*pstr)
+                throw std::bad_alloc();
+#endif
+        }
+        m_bstr = NULL;
+    }
 
     /**
@@ -262,5 +318,9 @@
      *  Takes the ownership of the returned data.
      */
-    BSTR *asOutParam() { setNull(); return &bstr; }
+    BSTR* asOutParam()
+    {
+        cleanup();
+        return &m_bstr;
+    }
 
     /**
@@ -271,31 +331,64 @@
 protected:
 
-    void safe_assign(CBSTR str)
-    {
-        if (bstr != str)
+    void cleanup()
+    {
+        if (m_bstr)
         {
-            setNull();
-            raw_copy(bstr, str);
+            ::SysFreeString(m_bstr);
+            m_bstr = NULL;
         }
     }
 
-    inline static void raw_copy(BSTR &ls, CBSTR rs)
-    {
-        if (rs)
-            ls = ::SysAllocString((const OLECHAR *) rs);
-    }
-
-    inline static void raw_copy(BSTR &ls, const char *rs)
-    {
-        if (rs)
+    /**
+     * Protected internal helper to copy a string. This ignores the previous object
+     * state, so either call this from a constructor or call cleanup() first.
+     *
+     * This variant copies from a zero-terminated UTF-16 string (which need not
+     * be a BSTR, i.e. need not have a length prefix).
+     *
+     * If the source is empty, this sets the member string to NULL.
+     * @param rs
+     */
+    void copyFrom(const OLECHAR *rs)
+    {
+        if (rs && *rs)
+        {
+            m_bstr = ::SysAllocString(rs);
+#ifdef RT_EXCEPTIONS_ENABLED
+            if (!m_bstr)
+                throw std::bad_alloc();
+#endif
+        }
+        else
+            m_bstr = NULL;
+    }
+
+    /**
+     * Protected internal helper to copy a string. This ignores the previous object
+     * state, so either call this from a constructor or call cleanup() first.
+     *
+     * This variant copies and converts from a zero-terminated UTF-8 string.
+     *
+     * If the source is empty, this sets the member string to NULL.
+     * @param rs
+     */
+    void copyFrom(const char *rs)
+    {
+        if (rs && *rs)
         {
             PRTUTF16 s = NULL;
             ::RTStrToUtf16(rs, &s);
-            raw_copy(ls, (BSTR)s);
+#ifdef RT_EXCEPTIONS_ENABLED
+            if (!s)
+                throw std::bad_alloc();
+#endif
+            copyFrom((const OLECHAR *)s);            // allocates BSTR from zero-terminated input string
             ::RTUtf16Free(s);
         }
-    }
-
-    BSTR bstr;
+        else
+            m_bstr = NULL;
+    }
+
+    BSTR m_bstr;
 
     friend class Utf8Str; /* to access our raw_copy() */
@@ -308,19 +401,21 @@
 inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
 
+// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
+WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
+
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
- *  Helper class that represents UTF8 (|char *|) strings. Useful in
- *  conjunction with Bstr to simplify conversions between UTF16 (|BSTR|)
- *  and UTF8.
- *
- *  This class uses COM/XPCOM-provided memory management routines to allocate
- *  and free string buffers. This makes it possible to:
- *  - use it as a type of member variables of COM/XPCOM components and pass
- *    their values to callers through component methods' output parameters
- *    using the #cloneTo() operation;
- *  - adopt (take ownership of) string buffers returned in output parameters
- *    of COM methods using the #asOutParam() operation and correctly free them
- *    afterwards.
+ *  String class used universally in Main for UTF-8 strings.
+ *
+ *  This is based on iprt::MiniString, to which some functionality has been
+ *  moved. Here we keep things that are specific to Main, such as conversions
+ *  with UTF-16 strings (Bstr).
+ *
+ *  Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
+ *  and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
+ *  behave the same. In both cases, MiniString allocates no memory, reports
+ *  a zero length and zero allocated bytes for both, and returns an empty
+ *  C string from c_str().
  */
 class Utf8Str : public iprt::MiniString
@@ -374,4 +469,5 @@
     }
 
+#if defined (VBOX_WITH_XPCOM)
     /**
      * Intended to assign instances to |char *| out parameters from within the
@@ -379,29 +475,11 @@
      * caller.
      *
-     * @remarks The returned string must be freed by RTStrFree, not RTMemFree.
-     */
-    const Utf8Str& cloneTo(char **pstr) const
-    {
-        if (pstr) /** @todo r=bird: This needs to if m_psz is NULL. Shouldn't it also throw std::bad_alloc? */
-            *pstr = RTStrDup(m_psz);
-        return *this;
-    }
-
-    /**
-     *  Intended to assign instances to |char *| out parameters from within the
-     *  interface method. Transfers the ownership of the original string to the
-     *  caller and resets the instance to null.
-     *
-     *  As opposed to cloneTo(), this method doesn't create a copy of the
-     *  string.
-     */
-    Utf8Str& detachTo(char **pstr)
-    {
-        *pstr = m_psz;
-        m_psz = NULL;
-        m_cbAllocated = 0;
-        m_cbLength = 0;
-        return *this;
-    }
+     * This allocates a single 0 byte in the target if the member string is empty.
+     *
+     * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
+     * like char* strings anyway.
+     */
+    void cloneTo(char **pstr) const;
+#endif
 
     /**
@@ -410,12 +488,11 @@
      *  caller.
      */
-    const Utf8Str& cloneTo(BSTR *pstr) const
+    void cloneTo(BSTR *pstr) const
     {
         if (pstr)
         {
-            *pstr = NULL;
-            Bstr::raw_copy(*pstr, m_psz);
+            Bstr bstr(*this);
+            bstr.cloneTo(pstr);
         }
-        return *this;
     }
 
@@ -505,5 +582,5 @@
     void copyFrom(CBSTR s)
     {
-        if (s)
+        if (s && *s)
         {
             RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This isn't throwing std::bad_alloc / handling return codes.
@@ -523,48 +600,4 @@
 };
 
-// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
-WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
-
-////////////////////////////////////////////////////////////////////////////////
-
-// inlined Bstr members that depend on Utf8Str
-
-inline Bstr::Bstr(const iprt::MiniString &that)
-    : bstr(NULL)
-{
-    raw_copy(bstr, that.c_str());
-}
-
-inline Bstr::Bstr(const char *that)
-    : bstr(NULL)
-{
-    raw_copy(bstr, that);
-}
-
-inline Bstr &Bstr::operator=(const Utf8Str &that)
-{
-    setNull();
-    raw_copy(bstr, that.c_str());
-    return *this;
-}
-inline Bstr &Bstr::operator=(const char *that)
-{
-    setNull();
-    raw_copy(bstr, that);
-    return *this;
-}
-
-inline const Bstr& Bstr::cloneTo(char **pstr) const
-{
-    if (pstr)
-    {
-        Utf8Str ustr(*this);
-        ustr.detachTo(pstr);
-    }
-    return *this;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 /**
  *  This class is a printf-like formatter for Utf8Str strings. Its purpose is
@@ -654,5 +687,5 @@
         va_list args;
         va_start(args, aFormat);
-        raw_copy(bstr, Utf8StrFmtVA(aFormat, args).c_str());
+        copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
         va_end(args);
     }
@@ -675,5 +708,5 @@
     BstrFmtVA(const char *aFormat, va_list aArgs)
     {
-        raw_copy(bstr, Utf8StrFmtVA(aFormat, aArgs).c_str());
+        copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
     }
 };
Index: /trunk/include/iprt/cpp/ministring.h
===================================================================
--- /trunk/include/iprt/cpp/ministring.h	(revision 26752)
+++ /trunk/include/iprt/cpp/ministring.h	(revision 26753)
@@ -45,4 +45,11 @@
  * else except IPRT memory management functions.  Semantics are like in
  * std::string, except it can do a lot less.
+ *
+ *
+ * Note that MiniString does not differentiate between NULL strings and
+ * empty strings. In other words, MiniString("") and MiniString(NULL)
+ * behave the same. In both cases, MiniString allocates no memory, reports
+ * a zero length and zero allocated bytes for both, and returns an empty
+ * C string from c_str().
  */
 #ifdef VBOX
@@ -71,5 +78,5 @@
      * Creates a copy of another MiniString.
      *
-     * This allocates s.length() + 1 bytes for the new instance.
+     * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
      *
      * @param   s               The source string.
@@ -83,7 +90,7 @@
 
     /**
-     * Creates a copy of another MiniString.
-     *
-     * This allocates strlen(pcsz) + 1 bytes for the new instance.
+     * Creates a copy of a C string.
+     *
+     * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
      *
      * @param   pcsz            The source string.
@@ -123,5 +130,5 @@
      *
      * Returns the number of bytes allocated in the internal string buffer, which is
-     * at least length() + 1 if length() > 0.
+     * at least length() + 1 if length() > 0; for an empty string, this returns 0.
      *
      * @returns m_cbAllocated.
@@ -172,5 +179,108 @@
 
     /**
+     * Assigns a copy of pcsz to "this".
+     *
+     * @param   pcsz            The source string.
+     *
+     * @throws  std::bad_alloc  On allocation failure.  The object is left describing
+     *             a NULL string.
+     *
+     * @returns Reference to the object.
+     */
+    MiniString &operator=(const char *pcsz)
+    {
+        if (m_psz != pcsz)
+        {
+            cleanup();
+            copyFrom(pcsz);
+        }
+        return *this;
+    }
+
+    /**
+     * Assigns a copy of s to "this".
+     *
+     * @param   s               The source string.
+     *
+     * @throws  std::bad_alloc  On allocation failure.  The object is left describing
+     *             a NULL string.
+     *
+     * @returns Reference to the object.
+     */
+    MiniString &operator=(const MiniString &s)
+    {
+        if (this != &s)
+        {
+            cleanup();
+            copyFrom(s);
+        }
+        return *this;
+    }
+
+    /**
+     * Appends the string "that" to "this".
+     *
+     * @param   that            The string to append.
+     *
+     * @throws  std::bad_alloc  On allocation error.  The object is left unchanged.
+     *
+     * @returns Reference to the object.
+     */
+    MiniString &append(const MiniString &that);
+
+    /**
+     * Appends the given character to "this".
+     *
+     * @param   c               The character to append.
+     *
+     * @throws  std::bad_alloc  On allocation error.  The object is left unchanged.
+     *
+     * @returns Reference to the object.
+     */
+    MiniString &append(char c);
+
+    /**
+     * Index operator.
+     *
+     * Returns the byte at the given index, or a null byte if the index is not
+     * smaller than length().  This does _not_ count codepoints but simply points
+     * into the member C string.
+     *
+     * @param   i       The index into the string buffer.
+     * @returns char at the index or null.
+     */
+    inline char operator[](size_t i) const
+    {
+        if (i < length())
+            return m_psz[i];
+        return '\0';
+    }
+
+    /**
+     * Returns the contained string as a C-style const char* pointer.
+     * This never returns NULL; if the string is empty, this returns a
+     * pointer to static null byte.
+     *
+     * @returns const pointer to C-style string.
+     */
+    inline const char *c_str() const
+    {
+        return (m_psz) ? m_psz : "";
+    }
+
+    /**
+     * Like c_str(), for compatibility with lots of VirtualBox Main code.
+     *
+     * @returns const pointer to C-style string.
+     */
+    inline const char *raw() const
+    {
+        return (m_psz) ? m_psz : "";
+    }
+
+    /**
      * Returns a non-const raw pointer that allows to modify the string directly.
+     * As opposed to c_str() and raw(), this DOES return NULL for an empty string
+     * because we cannot return a non-const pointer to a static "" global.
      *
      * @warning
@@ -209,107 +319,8 @@
 
     /**
-     * Assigns a copy of pcsz to "this".
-     *
-     * @param   pcsz            The source string.
-     *
-     * @throws  std::bad_alloc  On allocation failure.  The object is left describing
-     *             a NULL string.
-     *
-     * @returns Reference to the object.
-     */
-    MiniString &operator=(const char *pcsz)
-    {
-        if (m_psz != pcsz)
-        {
-            cleanup();
-            copyFrom(pcsz);
-        }
-        return *this;
-    }
-
-    /**
-     * Assigns a copy of s to "this".
-     *
-     * @param   s               The source string.
-     *
-     * @throws  std::bad_alloc  On allocation failure.  The object is left describing
-     *             a NULL string.
-     *
-     * @returns Reference to the object.
-     */
-    MiniString &operator=(const MiniString &s)
-    {
-        if (this != &s)
-        {
-            cleanup();
-            copyFrom(s);
-        }
-        return *this;
-    }
-
-    /**
-     * Appends the string "that" to "this".
-     *
-     * @param   that            The string to append.
-     *
-     * @throws  std::bad_alloc  On allocation error.  The object is left unchanged.
-     *
-     * @returns Reference to the object.
-     */
-    MiniString &append(const MiniString &that);
-
-    /**
-     * Appends the given character to "this".
-     *
-     * @param   c               The character to append.
-     *
-     * @throws  std::bad_alloc  On allocation error.  The object is left unchanged.
-     *
-     * @returns Reference to the object.
-     */
-    MiniString &append(char c);
-
-    /**
-     * Index operator.
-     *
-     * Returns the byte at the given index, or a null byte if the index is not
-     * smaller than length().  This does _not_ count codepoints but simply points
-     * into the member C string.
-     *
-     * @param   i       The index into the string buffer.
-     * @returns char at the index or null.
-     */
-    inline char operator[](size_t i) const
-    {
-        if (i < length())
-            return m_psz[i];
-        return '\0';
-    }
-
-    /**
-     * Returns the contained string as a C-style const char* pointer.
-     *
-     * @returns const pointer to C-style string.
-     */
-    inline const char *c_str() const
-    {
-        return m_psz;
-    }
-
-    /**
-     * Like c_str(), for compatibility with lots of VirtualBox Main code.
-     *
-     * @returns const pointer to C-style string.
-     */
-    inline const char *raw() const
-    {
-        return m_psz;
-    }
-
-    /**
-     * Emptry string or not?
-     *
-     * Returns true if the member string has no length.  This states nothing about
-     * how much memory might be allocated.
+     * Returns true if the member string has no length.
+     * This is true for instances created from both NULL and "" input strings.
+     *
+     * This states nothing about how much memory might be allocated.
      *
      * @returns true if empty, false if not.
@@ -474,5 +485,5 @@
      * Hide operator bool() to force people to use isEmpty() explicitly.
      */
-    operator bool() const { return false; }
+    operator bool() const;
 
     /**
@@ -492,6 +503,6 @@
 
     /**
-     * Protected internal helper for copy a string that completely ignors the
-     * current object state.
+     * Protected internal helper to copy a string. This ignores the previous object
+     * state, so either call this from a constructor or call cleanup() first.
      *
      * copyFrom() unconditionally sets the members to a copy of the given other
@@ -501,5 +512,5 @@
      *
      * This variant copies from another MiniString and is fast since
-     * the length of source string is known.
+     * the length of the source string is known.
      *
      * @param   s               The source string.
@@ -533,6 +544,6 @@
 
     /**
-     * Protected internal helper for copy a string that completely ignors the
-     * current object state.
+     * Protected internal helper to copy a string. This ignores the previous object
+     * state, so either call this from a constructor or call cleanup() first.
      *
      * See copyFrom() above.
@@ -548,5 +559,5 @@
     void copyFrom(const char *pcsz)
     {
-        if (pcsz)
+        if (pcsz && *pcsz)
         {
             m_cbLength = strlen(pcsz);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 26752)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 26753)
@@ -281,8 +281,9 @@
         bool doClose = false;
 
-        if (!comment.isNull())
+        if (!comment.isEmpty())
         {
             CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
         }
+
         ComPtr<IProgress> progress;
         CHECK_ERROR(hardDisk, CreateBaseStorage(sizeMB, DiskVariant, progress.asOutParam()));
@@ -1038,5 +1039,5 @@
         if (FAILED(rc)) break;
 
-        if (!port.isNull())
+        if (!port.isEmpty())
             server = BstrFmt ("%ls:%ls", server.raw(), port.raw());
 
@@ -1049,15 +1050,15 @@
         target.detachTo (values.appendedRaw());
 
-        if (!lun.isNull())
+        if (!lun.isEmpty())
         {
             Bstr ("LUN").detachTo (names.appendedRaw());
             lun.detachTo (values.appendedRaw());
         }
-        if (!username.isNull())
+        if (!username.isEmpty())
         {
             Bstr ("InitiatorUsername").detachTo (names.appendedRaw());
             username.detachTo (values.appendedRaw());
         }
-        if (!password.isNull())
+        if (!password.isEmpty())
         {
             Bstr ("InitiatorSecret").detachTo (names.appendedRaw());
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp	(revision 26752)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp	(revision 26753)
@@ -441,14 +441,14 @@
                 if (!f.mActive.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
-                if (!f.mVendorId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
-                if (!f.mProductId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
-                if (!f.mRevision.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
-                if (!f.mManufacturer.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
-                if (!f.mSerialNumber.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
+                if (!f.mVendorId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
+                if (!f.mProductId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
+                if (!f.mRevision.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
+                if (!f.mManufacturer.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
+                if (!f.mSerialNumber.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
                 if (!f.mMaskedInterfaces.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
@@ -466,16 +466,16 @@
                 if (!f.mActive.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
-                if (!f.mVendorId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
-                if (!f.mProductId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
-                if (!f.mRevision.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
-                if (!f.mManufacturer.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
-                if (!f.mRemote.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
-                if (!f.mSerialNumber.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
+                if (!f.mVendorId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
+                if (!f.mProductId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
+                if (!f.mRevision.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
+                if (!f.mManufacturer.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
+                if (!f.mRemote.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote));
+                if (!f.mSerialNumber.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
                 if (!f.mMaskedInterfaces.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
@@ -494,18 +494,18 @@
                 ComPtr <IHostUSBDeviceFilter> flt = coll[cmd.mIndex];
 
-                if (!f.mName.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
+                if (!f.mName.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName));
                 if (!f.mActive.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
-                if (!f.mVendorId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
-                if (!f.mProductId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
-                if (!f.mRevision.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
-                if (!f.mManufacturer.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
-                if (!f.mSerialNumber.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
+                if (!f.mVendorId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
+                if (!f.mProductId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
+                if (!f.mRevision.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
+                if (!f.mManufacturer.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
+                if (!f.mSerialNumber.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
                 if (!f.mMaskedInterfaces.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
@@ -521,20 +521,20 @@
                 ComPtr <IUSBDeviceFilter> flt = coll[cmd.mIndex];
 
-                if (!f.mName.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName.setNullIfEmpty()));
+                if (!f.mName.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Name) (f.mName));
                 if (!f.mActive.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(Active) (f.mActive));
-                if (!f.mVendorId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId.setNullIfEmpty()));
-                if (!f.mProductId.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId.setNullIfEmpty()));
-                if (!f.mRevision.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision.setNullIfEmpty()));
-                if (!f.mManufacturer.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer.setNullIfEmpty()));
-                if (!f.mRemote.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote.setNullIfEmpty()));
-                if (!f.mSerialNumber.isNull())
-                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber.setNullIfEmpty()));
+                if (!f.mVendorId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(VendorId) (f.mVendorId));
+                if (!f.mProductId.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(ProductId) (f.mProductId));
+                if (!f.mRevision.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Revision) (f.mRevision));
+                if (!f.mManufacturer.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Manufacturer) (f.mManufacturer));
+                if (!f.mRemote.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(Remote) (f.mRemote));
+                if (!f.mSerialNumber.isEmpty())
+                    CHECK_ERROR_BREAK (flt, COMSETTER(SerialNumber) (f.mSerialNumber));
                 if (!f.mMaskedInterfaces.isNull())
                     CHECK_ERROR_BREAK (flt, COMSETTER(MaskedInterfaces) (f.mMaskedInterfaces));
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 26752)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 26753)
@@ -232,5 +232,5 @@
             return E_INVALIDARG;
 
-        if (com::asGuidStr(id).isNull())
+        if (com::asGuidStr(id).isEmpty())
         {
             /* it's a global extra data key someone wants to change */
@@ -314,5 +314,5 @@
                                   IN_BSTR key, IN_BSTR value)
     {
-        if (com::asGuidStr(id).isNull())
+        if (com::asGuidStr(id).isEmpty())
         {
             QString sKey = QString::fromUtf16 (key);
Index: /trunk/src/VBox/Main/ApplianceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ApplianceImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/ApplianceImpl.cpp	(revision 26753)
@@ -1569,5 +1569,5 @@
                                                     mhda.lDevice,
                                                     DeviceType_Floppy,
-                                                    Bstr(""));
+                                                    NULL);
                         if (FAILED(rc)) throw rc;
 
@@ -1618,5 +1618,5 @@
                                                     mhda.lDevice,
                                                     DeviceType_DVD,
-                                                    Bstr(""));
+                                                    NULL);
                         if (FAILED(rc)) throw rc;
 
@@ -1744,5 +1744,8 @@
                             rc = mVirtualBox->OpenHardDisk(Bstr(strSrcFilePath),
                                                            AccessMode_ReadOnly,
-                                                           false, Bstr(""), false, Bstr(""),
+                                                           false,
+                                                           NULL,
+                                                           false,
+                                                           NULL,
                                                            srcHdVBox.asOutParam());
                             if (FAILED(rc)) throw rc;
@@ -4281,7 +4284,4 @@
                                                       IN_BSTR aExtraConfigValue)
 {
-    CheckComArgNotNull(aVboxValue);
-    CheckComArgNotNull(aExtraConfigValue);
-
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 26753)
@@ -574,7 +574,7 @@
 {
     if (!enabledGuestPropertiesVRDP())
-    {
         return;
-    }
+
+    Bstr bstrReadOnlyGuest(L"RDONLYGUEST");
 
     int rc;
@@ -584,5 +584,5 @@
     if (RT_SUCCESS(rc))
     {
-        mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
+        mMachine->SetGuestProperty(Bstr(pszPropertyName), NULL, bstrReadOnlyGuest);
         RTStrFree(pszPropertyName);
     }
@@ -591,5 +591,5 @@
     if (RT_SUCCESS(rc))
     {
-        mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
+        mMachine->SetGuestProperty(Bstr(pszPropertyName), NULL, bstrReadOnlyGuest);
         RTStrFree(pszPropertyName);
     }
@@ -598,5 +598,5 @@
     if (RT_SUCCESS(rc))
     {
-        mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
+        mMachine->SetGuestProperty(Bstr(pszPropertyName), NULL, bstrReadOnlyGuest);
         RTStrFree(pszPropertyName);
     }
@@ -606,5 +606,5 @@
     if (RT_SUCCESS(rc))
     {
-        mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VRDP/LastDisconnectedClient"), Bstr(pszClientId), Bstr("RDONLYGUEST"));
+        mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VRDP/LastDisconnectedClient"), Bstr(pszClientId), bstrReadOnlyGuest);
         RTStrFree(pszClientId);
     }
@@ -1190,7 +1190,8 @@
 
 // static
-DECLCALLBACK(int)
-Console::doGuestPropNotification(void *pvExtension, uint32_t u32Function,
-                                 void *pvParms, uint32_t cbParms)
+DECLCALLBACK(int) Console::doGuestPropNotification(void *pvExtension,
+                                                   uint32_t u32Function,
+                                                   void *pvParms,
+                                                   uint32_t cbParms)
 {
     using namespace guestProp;
@@ -1212,25 +1213,17 @@
     Bstr value(pCBData->pcszValue);
     Bstr flags(pCBData->pcszFlags);
-    if (   !name.isNull()
-        && (!value.isNull() || pCBData->pcszValue == NULL)
-        && (!flags.isNull() || pCBData->pcszFlags == NULL)
-       )
-    {
-        ComObjPtr<Console> ptrConsole = reinterpret_cast<Console *>(pvExtension);
-        HRESULT hrc = ptrConsole->mControl->PushGuestProperty(name,
-                                                              value,
-                                                              pCBData->u64Timestamp,
-                                                              flags);
-        if (SUCCEEDED(hrc))
-            rc = VINF_SUCCESS;
-        else
-        {
-            LogFunc(("Console::doGuestPropNotification: hrc=%Rhrc pCBData={.pcszName=%s, .pcszValue=%s, .pcszFlags=%s}\n",
-                     pCBData->pcszName, pCBData->pcszValue, pCBData->pcszFlags));
-            rc = Global::vboxStatusCodeFromCOM(hrc);
-        }
-    }
+    ComObjPtr<Console> ptrConsole = reinterpret_cast<Console *>(pvExtension);
+    HRESULT hrc = ptrConsole->mControl->PushGuestProperty(name,
+                                                          value,
+                                                          pCBData->u64Timestamp,
+                                                          flags);
+    if (SUCCEEDED(hrc))
+        rc = VINF_SUCCESS;
     else
-        rc = VERR_NO_MEMORY;
+    {
+        LogFunc(("Console::doGuestPropNotification: hrc=%Rhrc pCBData={.pcszName=%s, .pcszValue=%s, .pcszFlags=%s}\n",
+                 pCBData->pcszName, pCBData->pcszValue, pCBData->pcszFlags));
+        rc = Global::vboxStatusCodeFromCOM(hrc);
+    }
     return rc;
 }
@@ -1248,4 +1241,12 @@
     Utf8Str utf8Patterns(aPatterns);
     parm[0].type = VBOX_HGCM_SVC_PARM_PTR;
+    // mutableRaw() returns NULL for an empty string
+//     if ((parm[0].u.pointer.addr = utf8Patterns.mutableRaw()))
+//         parm[0].u.pointer.size = (uint32_t)utf8Patterns.length() + 1;
+//     else
+//     {
+//         parm[0].u.pointer.addr = (void*)"";
+//         parm[0].u.pointer.size = 1;
+//     }
     parm[0].u.pointer.addr = utf8Patterns.mutableRaw();
     parm[0].u.pointer.size = (uint32_t)utf8Patterns.length() + 1;
@@ -1364,6 +1365,7 @@
     try
     {
-        Bstr                pattern("");
-        hrc = doEnumerateGuestProperties(pattern, ComSafeArrayAsOutParam(namesOut),
+        Bstr pattern;
+        hrc = doEnumerateGuestProperties(pattern,
+                                         ComSafeArrayAsOutParam(namesOut),
                                          ComSafeArrayAsOutParam(valuesOut),
                                          ComSafeArrayAsOutParam(timestampsOut),
@@ -1371,8 +1373,8 @@
         if (SUCCEEDED(hrc))
         {
-            std::vector <BSTR>      names;
-            std::vector <BSTR>      values;
-            std::vector <ULONG64>   timestamps;
-            std::vector <BSTR>      flags;
+            std::vector<BSTR>      names;
+            std::vector<BSTR>      values;
+            std::vector<ULONG64>   timestamps;
+            std::vector<BSTR>      flags;
             for (size_t i = 0; i < namesOut.size(); ++i)
             {
@@ -1392,10 +1394,4 @@
             com::SafeArray<ULONG64> timestampsIn(timestamps);
             com::SafeArray<BSTR>    flagsIn(flags);
-            if (   namesIn.isNull()
-                || valuesIn.isNull()
-                || timestampsIn.isNull()
-                || flagsIn.isNull()
-               )
-                throw std::bad_alloc();
             /* PushGuestProperties() calls DiscardSettings(), which calls us back */
             mControl->PushGuestProperties(ComSafeArrayAsInParam(namesIn),
@@ -2594,5 +2590,5 @@
 {
 #ifdef VBOX_WITH_USB
-    CheckComArgNotNull(aAddress);
+    CheckComArgStrNotEmptyOrNull(aAddress);
     CheckComArgOutPointerValid(aDevice);
 
@@ -2664,6 +2660,6 @@
 Console::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable)
 {
-    CheckComArgNotNull(aName);
-    CheckComArgNotNull(aHostPath);
+    CheckComArgStrNotEmptyOrNull(aName);
+    CheckComArgStrNotEmptyOrNull(aHostPath);
 
     AutoCaller autoCaller(this);
@@ -2732,5 +2728,5 @@
 STDMETHODIMP Console::RemoveSharedFolder(IN_BSTR aName)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
 
     AutoCaller autoCaller(this);
@@ -2798,5 +2794,5 @@
     LogFlowThisFunc(("aName='%ls' mMachineState=%08X\n", aName, mMachineState));
 
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutPointerValid(aProgress);
 
@@ -7725,6 +7721,6 @@
          * (i.e. creating a snapshot online)
          */
-        ComAssertThrow(    (!pTask->bstrSavedStateFile.isNull() && pTask->fTakingSnapshotOnline)
-                        || (pTask->bstrSavedStateFile.isNull() && !pTask->fTakingSnapshotOnline),
+        ComAssertThrow(    (!pTask->bstrSavedStateFile.isEmpty() &&  pTask->fTakingSnapshotOnline)
+                        || ( pTask->bstrSavedStateFile.isEmpty() && !pTask->fTakingSnapshotOnline),
                        rc = E_FAIL);
 
@@ -8040,5 +8036,5 @@
             task->mProgress->notifyComplete(rc,
                                             COM_IIDOF(IConsole),
-                                            Console::getComponentName(),
+                                            (CBSTR)Console::getComponentName(),
                                             errMsg.c_str());
         else
Index: /trunk/src/VBox/Main/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/ConsoleImpl2.cpp	(revision 26753)
@@ -3180,5 +3180,5 @@
                 }
 
-                if (!networkName.isNull())
+                if (!networkName.isEmpty())
                 {
                     /*
@@ -3187,5 +3187,5 @@
                      */
                     ComPtr<IDHCPServer> dhcpServer;
-                    hrc = virtualBox->FindDHCPServerByNetworkName(networkName.mutableRaw(), dhcpServer.asOutParam());
+                    hrc = virtualBox->FindDHCPServerByNetworkName(networkName, dhcpServer.asOutParam());
                     if (SUCCEEDED(hrc))
                     {
Index: /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 26753)
@@ -903,5 +903,5 @@
     CheckComArgOutPointerValid(aProgress);
     CheckComArgStrNotEmptyOrNull(aHostname);
-    CheckComArgNotNull(aHostname);
+    CheckComArgStrNotEmptyOrNull(aHostname);
     CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort));
     CheckComArgExprMsg(aMaxDowntime, aMaxDowntime > 0, ("is %u", aMaxDowntime));
Index: /trunk/src/VBox/Main/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/GuestImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/GuestImpl.cpp	(revision 26753)
@@ -127,6 +127,6 @@
 
     // redirect the call to IMachine if no additions are installed
-    if (mData.mAdditionsVersion.isNull())
-        return mParent->machine()->COMGETTER(OSTypeId) (aOSTypeId);
+    if (mData.mAdditionsVersion.isEmpty())
+        return mParent->machine()->COMGETTER(OSTypeId)(aOSTypeId);
 
     mData.mOSTypeId.cloneTo(aOSTypeId);
@@ -262,8 +262,4 @@
                                    IN_BSTR aDomain, BOOL aAllowInteractiveLogon)
 {
-    CheckComArgNotNull(aUserName);
-    CheckComArgNotNull(aPassword);
-    CheckComArgNotNull(aDomain);
-
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -315,8 +311,6 @@
 /////////////////////////////////////////////////////////////////////////////
 
-void Guest::setAdditionsVersion (Bstr aVersion, VBOXOSTYPE aOsType)
-{
-    Assert(aVersion.isNull() || !aVersion.isEmpty());
-
+void Guest::setAdditionsVersion(Bstr aVersion, VBOXOSTYPE aOsType)
+{
     AutoCaller autoCaller(this);
     AssertComRCReturnVoid (autoCaller.rc());
@@ -325,5 +319,5 @@
 
     mData.mAdditionsVersion = aVersion;
-    mData.mAdditionsActive = !aVersion.isNull();
+    mData.mAdditionsActive = !aVersion.isEmpty();
 
     mData.mOSTypeId = Global::OSTypeId (aOsType);
Index: /trunk/src/VBox/Main/HostImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/HostImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/HostImpl.cpp	(revision 26753)
@@ -451,8 +451,5 @@
     if(hr == S_OK)
     {
-        size_t cUnicodeName = wcslen(lpszName) + 1;
-        size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
-        Bstr name (uniLen + 1 /* extra zero */);
-        wcscpy((wchar_t *) name.mutableRaw(), lpszName);
+        Bstr name((CBSTR)lpszName);
 
         hr = pncc->GetInstanceGuid(&IfGuid);
@@ -1290,5 +1287,5 @@
 STDMETHODIMP Host::FindHostDVDDrive(IN_BSTR aName, IMedium **aDrive)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutPointerValid(aDrive);
 
@@ -1317,5 +1314,5 @@
 STDMETHODIMP Host::FindHostFloppyDrive(IN_BSTR aName, IMedium **aDrive)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutPointerValid(aDrive);
 
@@ -1451,5 +1448,5 @@
 {
 #ifdef VBOX_WITH_USB
-    CheckComArgNotNull(aAddress);
+    CheckComArgStrNotEmptyOrNull(aAddress);
     CheckComArgOutPointerValid(aDevice);
 
Index: /trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/HostNetworkInterfaceImpl.cpp	(revision 26753)
@@ -423,7 +423,7 @@
             {
                 m.realIPAddress = 0;
-                if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw())), Bstr(""))))
+                if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()), NULL)))
                     return E_FAIL;
-                if (FAILED(mVBox->SetExtraData(Bstr(Utf8StrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw())), Bstr(""))))
+                if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw()), NULL)))
                     return E_FAIL;
                 return S_OK;
Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 26753)
@@ -697,9 +697,5 @@
 STDMETHODIMP Machine::COMSETTER(Name)(IN_BSTR aName)
 {
-    CheckComArgNotNull(aName);
-
-    if (!*aName)
-        return setError(E_INVALIDARG,
-                        tr("Machine name cannot be empty"));
+    CheckComArgStrNotEmptyOrNull(aName);
 
     AutoCaller autoCaller(this);
@@ -779,5 +775,5 @@
 STDMETHODIMP Machine::COMSETTER(OSTypeId)(IN_BSTR aOSTypeId)
 {
-    CheckComArgNotNull(aOSTypeId);
+    CheckComArgStrNotEmptyOrNull(aOSTypeId);
 
     AutoCaller autoCaller(this);
@@ -1930,8 +1926,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (mData->mSession.mType.isNull())
-        Bstr("").cloneTo(aSessionType);
-    else
-        mData->mSession.mType.cloneTo(aSessionType);
+    mData->mSession.mType.cloneTo(aSessionType);
 
     return S_OK;
@@ -1990,8 +1983,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (mSSData->mStateFilePath.isEmpty())
-        Bstr("").cloneTo(aStateFilePath);
-    else
-        mSSData->mStateFilePath.cloneTo(aStateFilePath);
+    mSSData->mStateFilePath.cloneTo(aStateFilePath);
 
     return S_OK;
@@ -2137,5 +2127,4 @@
 Machine::COMSETTER(GuestPropertyNotificationPatterns)(IN_BSTR aPatterns)
 {
-    CheckComArgNotNull(aPatterns);
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2403,6 +2392,5 @@
                      aControllerName, aControllerPort, aDevice, aType, aId));
 
-    CheckComArgNotNull(aControllerName);
-    CheckComArgNotNull(aId);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
 
     AutoCaller autoCaller(this);
@@ -2829,5 +2817,5 @@
                                    LONG aDevice)
 {
-    CheckComArgNotNull(aControllerName);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
 
     LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld\n",
@@ -2914,5 +2902,5 @@
                                         LONG aDevice, BOOL aPassthrough)
 {
-    CheckComArgNotNull(aControllerName);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
 
     LogFlowThisFunc(("aControllerName=\"%ls\" aControllerPort=%ld aDevice=%ld aPassthrough=%d\n",
@@ -2968,6 +2956,6 @@
                      aControllerName, aControllerPort, aDevice, aForce));
 
-    CheckComArgNotNull(aControllerName);
-    CheckComArgNotNull(aId);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
+    CheckComArgStrNotEmptyOrNull(aId);
 
     AutoCaller autoCaller(this);
@@ -3109,5 +3097,5 @@
                      aControllerName, aControllerPort, aDevice));
 
-    CheckComArgNotNull(aControllerName);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
     CheckComArgOutPointerValid(aMedium);
 
@@ -3208,5 +3196,5 @@
                                    BSTR *aValue)
 {
-    CheckComArgNotNull(aKey);
+    CheckComArgStrNotEmptyOrNull(aKey);
     CheckComArgOutPointerValid(aValue);
 
@@ -3235,5 +3223,5 @@
 STDMETHODIMP Machine::SetExtraData(IN_BSTR aKey, IN_BSTR aValue)
 {
-    CheckComArgNotNull(aKey);
+    CheckComArgStrNotEmptyOrNull(aKey);
 
     AutoCaller autoCaller(this);
@@ -3266,14 +3254,10 @@
         // lock to copy the list of callbacks to invoke
         Bstr error;
-        Bstr bstrValue;
-        if (aValue)
-            bstrValue = aValue;
-        else
-            bstrValue = (const char *)"";
+        Bstr bstrValue(aValue);
 
         if (!mParent->onExtraDataCanChange(mData->mUuid, aKey, bstrValue, error))
         {
             const char *sep = error.isEmpty() ? "" : ": ";
-            CBSTR err = error.isNull() ? (CBSTR) L"" : error.raw();
+            CBSTR err = error.raw();
             LogWarningFunc(("Someone vetoed! Change refused%s%ls\n",
                             sep, err));
@@ -3459,5 +3443,5 @@
 STDMETHODIMP Machine::FindSnapshot(IN_BSTR aName, ISnapshot **aSnapshot)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutPointerValid(aSnapshot);
 
@@ -3485,6 +3469,6 @@
 STDMETHODIMP Machine::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable)
 {
-    CheckComArgNotNull(aName);
-    CheckComArgNotNull(aHostPath);
+    CheckComArgStrNotEmptyOrNull(aName);
+    CheckComArgStrNotEmptyOrNull(aHostPath);
 
     AutoCaller autoCaller(this);
@@ -3520,5 +3504,5 @@
 STDMETHODIMP Machine::RemoveSharedFolder(IN_BSTR aName)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
 
     AutoCaller autoCaller(this);
@@ -3610,5 +3594,5 @@
     ReturnComNotImplemented();
 #else // VBOX_WITH_GUEST_PROPS
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutPointerValid(aValue);
     CheckComArgOutPointerValid(aTimestamp);
@@ -3689,6 +3673,5 @@
     using namespace guestProp;
 
-    CheckComArgNotNull(aName);
-    CheckComArgNotNull(aValue);
+    CheckComArgStrNotEmptyOrNull(aName);
     if ((aFlags != NULL) && !VALID_PTR(aFlags))
         return E_INVALIDARG;
@@ -3934,5 +3917,5 @@
                      aControllerName, aControllerPort, aDevice));
 
-    CheckComArgNotNull(aControllerName);
+    CheckComArgStrNotEmptyOrNull(aControllerName);
     CheckComArgOutPointerValid(aAttachment);
 
@@ -8950,5 +8933,5 @@
 #endif /* VBOX_WITH_USB */
 
-    if (!mData->mSession.mType.isNull())
+    if (!mData->mSession.mType.isEmpty())
     {
         /* mType is not null when this machine's process has been started by
@@ -9658,5 +9641,5 @@
     using namespace guestProp;
 
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     if (aValue != NULL && (!VALID_PTR(aValue) || !VALID_PTR(aFlags)))
         return E_POINTER;  /* aValue can be NULL to indicate deletion */
Index: /trunk/src/VBox/Main/Matching.cpp
===================================================================
--- /trunk/src/VBox/Main/Matching.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/Matching.cpp	(revision 26753)
@@ -196,8 +196,7 @@
 
     // empty or null mSimple matches any match
-    return
-        mSimple.isEmpty() ||
-        (mIgnoreCase && mSimple.compareIgnoreCase (aValue) == 0) ||
-        (!mIgnoreCase && mSimple.compare (aValue) == 0);
+    return     mSimple.isEmpty()
+            || (mIgnoreCase && mSimple.compare(aValue, Bstr::CaseInsensitive) == 0)
+            || (!mIgnoreCase && mSimple.compare(aValue) == 0);
 }
 
Index: /trunk/src/VBox/Main/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MediumImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/MediumImpl.cpp	(revision 26753)
@@ -1361,8 +1361,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (m->strDescription.isEmpty())
-        Bstr("").cloneTo(aDescription);
-    else
-        m->strDescription.cloneTo(aDescription);
+    m->strDescription.cloneTo(aDescription);
 
     return S_OK;
@@ -1371,6 +1368,4 @@
 STDMETHODIMP Medium::COMSETTER(Description)(IN_BSTR aDescription)
 {
-    CheckComArgNotNull(aDescription);
-
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -1415,5 +1410,5 @@
 STDMETHODIMP Medium::COMSETTER(Location)(IN_BSTR aLocation)
 {
-    CheckComArgNotNull(aLocation);
+    CheckComArgStrNotEmptyOrNull(aLocation);
 
     AutoCaller autoCaller(this);
@@ -1725,8 +1720,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (m->strLastAccessError.isEmpty())
-        Bstr("").cloneTo(aLastAccessError);
-    else
-        m->strLastAccessError.cloneTo(aLastAccessError);
+    m->strLastAccessError.cloneTo(aLastAccessError);
 
     return S_OK;
@@ -2102,8 +2094,5 @@
                         tr("Property '%ls' does not exist"), aName);
 
-    if (it->second.isEmpty())
-        Bstr("").cloneTo(aValue);
-    else
-        it->second.cloneTo(aValue);
+    it->second.cloneTo(aValue);
 
     return S_OK;
@@ -2169,9 +2158,6 @@
     {
         it->first.cloneTo(&names[i]);
-        if (it->second.isEmpty())
-            Bstr("").cloneTo(&values[i]);
-        else
-            it->second.cloneTo(&values[i]);
-        ++ i;
+        it->second.cloneTo(&values[i]);
+        ++i;
     }
 
@@ -2362,7 +2348,7 @@
 
 STDMETHODIMP Medium::CloneTo(IMedium *aTarget,
-                              MediumVariant_T aVariant,
-                              IMedium *aParent,
-                              IProgress **aProgress)
+                             MediumVariant_T aVariant,
+                             IMedium *aParent,
+                             IProgress **aProgress)
 {
     CheckComArgNotNull(aTarget);
@@ -3090,5 +3076,5 @@
     {
         /* only save properties that have non-default values */
-        if (!it->second.isNull())
+        if (!it->second.isEmpty())
         {
             Utf8Str name = it->first;
@@ -4858,5 +4844,5 @@
 
     /* we interpret null values as "no value" in Medium */
-    if (it->second.isNull())
+    if (it->second.isEmpty())
         return VERR_CFGM_VALUE_NOT_FOUND;
 
@@ -4885,5 +4871,5 @@
 
     /* we interpret null values as "no value" in Medium */
-    if (it->second.isNull())
+    if (it->second.isEmpty())
         return VERR_CFGM_VALUE_NOT_FOUND;
 
Index: /trunk/src/VBox/Main/NetworkAdapterImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/NetworkAdapterImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/NetworkAdapterImpl.cpp	(revision 26753)
@@ -1026,6 +1026,4 @@
         case NetworkAttachmentType_NAT:
             mData->mNATNetwork = data.strName;
-            if (mData->mNATNetwork.isNull())
-                mData->mNATNetwork = "";
             rc = AttachToNAT();
             if (FAILED(rc)) return rc;
@@ -1041,5 +1039,5 @@
         case NetworkAttachmentType_Internal:
             mData->mInternalNetwork = data.strName;
-            Assert(!mData->mInternalNetwork.isNull());
+            Assert(!mData->mInternalNetwork.isEmpty());
 
             rc = AttachToInternalNetwork();
Index: /trunk/src/VBox/Main/RemoteUSBDeviceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/RemoteUSBDeviceImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/RemoteUSBDeviceImpl.cpp	(revision 26753)
@@ -142,5 +142,5 @@
 
     /* this is const, no need to lock */
-    Bstr(mData.id).cloneTo(aId);
+    mData.id.toUtf16().detachTo(aId);
 
     return S_OK;
Index: /trunk/src/VBox/Main/SessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SessionImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/SessionImpl.cpp	(revision 26753)
@@ -694,5 +694,5 @@
                         Global::stringifySessionState(mState));
     AssertReturn(mType == SessionType_Direct, VBOX_E_INVALID_OBJECT_STATE);
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     if (!aIsSetter && !VALID_PTR(aRetValue))
         return E_POINTER;
Index: /trunk/src/VBox/Main/SharedFolderImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SharedFolderImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/SharedFolderImpl.cpp	(revision 26753)
@@ -333,8 +333,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (m.lastAccessError.isEmpty())
-        Bstr("").cloneTo(aLastAccessError);
-    else
-        m.lastAccessError.cloneTo(aLastAccessError);
+    m.lastAccessError.cloneTo(aLastAccessError);
 
     return S_OK;
Index: /trunk/src/VBox/Main/SnapshotImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SnapshotImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/SnapshotImpl.cpp	(revision 26753)
@@ -342,5 +342,5 @@
 STDMETHODIMP Snapshot::COMSETTER(Name)(IN_BSTR aName)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
 
     AutoCaller autoCaller(this);
@@ -378,6 +378,4 @@
 STDMETHODIMP Snapshot::COMSETTER(Description)(IN_BSTR aDescription)
 {
-    CheckComArgNotNull(aDescription);
-
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
Index: /trunk/src/VBox/Main/SystemPropertiesImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/SystemPropertiesImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/SystemPropertiesImpl.cpp	(revision 26753)
@@ -828,5 +828,5 @@
         /* MediumFormat is all const, no need to lock */
 
-        if ((*it)->id().compareIgnoreCase (aFormat) == 0)
+        if ((*it)->id().compare(aFormat, Bstr::CaseInsensitive) == 0)
         {
             format = *it;
Index: /trunk/src/VBox/Main/USBControllerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/USBControllerImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/USBControllerImpl.cpp	(revision 26753)
@@ -1110,5 +1110,5 @@
     rc = aUSBDevice->COMGETTER(Manufacturer) (manufacturer.asOutParam());
     ComAssertComRCRet(rc, false);
-    if (!manufacturer.isNull())
+    if (!manufacturer.isEmpty())
         USBFilterSetStringExact (&dev, USBFILTERIDX_MANUFACTURER_STR, Utf8Str(manufacturer).c_str(), true);
 
@@ -1116,5 +1116,5 @@
     rc = aUSBDevice->COMGETTER(Product) (product.asOutParam());
     ComAssertComRCRet(rc, false);
-    if (!product.isNull())
+    if (!product.isEmpty())
         USBFilterSetStringExact (&dev, USBFILTERIDX_PRODUCT_STR, Utf8Str(product).c_str(), true);
 
@@ -1122,5 +1122,5 @@
     rc = aUSBDevice->COMGETTER(SerialNumber) (serialNumber.asOutParam());
     ComAssertComRCRet(rc, false);
-    if (!serialNumber.isNull())
+    if (!serialNumber.isEmpty())
         USBFilterSetStringExact (&dev, USBFILTERIDX_SERIAL_NUMBER_STR, Utf8Str(serialNumber).c_str(), true);
 
Index: /trunk/src/VBox/Main/USBDeviceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/USBDeviceImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/USBDeviceImpl.cpp	(revision 26753)
@@ -155,5 +155,5 @@
 
     /* this is const, no need to lock */
-    Guid(mData.id).toString().cloneTo(aId);
+    Guid(mData.id).toUtf16().detachTo(aId);
 
     return S_OK;
Index: /trunk/src/VBox/Main/VFSExplorerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VFSExplorerImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/VFSExplorerImpl.cpp	(revision 26753)
@@ -561,5 +561,5 @@
 STDMETHODIMP VFSExplorer::Cd(IN_BSTR aDir, IProgress **aProgress)
 {
-    CheckComArgNotNull(aDir);
+    CheckComArgStrNotEmptyOrNull(aDir);
     CheckComArgOutPointerValid(aProgress);
 
Index: /trunk/src/VBox/Main/VirtualBoxBase.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxBase.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/VirtualBoxBase.cpp	(revision 26753)
@@ -810,17 +810,21 @@
  */
 /* static */
-HRESULT VirtualBoxSupportErrorInfoImplBase::setErrorInternal (
-    HRESULT aResultCode, const GUID &aIID,
-    const Bstr &aComponent, const Bstr &aText,
-    bool aWarning, bool aLogIt)
+HRESULT VirtualBoxSupportErrorInfoImplBase::setErrorInternal(HRESULT aResultCode,
+                                                             const GUID &aIID,
+                                                             const wchar_t *aComponent,
+                                                             const Bstr &aText,
+                                                             bool aWarning,
+                                                             bool aLogIt)
 {
     /* whether multi-error mode is turned on */
-    bool preserve = ((uintptr_t) RTTlsGet (MultiResult::sCounter)) > 0;
+    bool preserve = ((uintptr_t)RTTlsGet(MultiResult::sCounter)) > 0;
+
+    Bstr bstrComponent((CBSTR)aComponent);
 
     if (aLogIt)
-        LogRel (("ERROR [COM]: aRC=%Rhrc (%#08x) aIID={%RTuuid} aComponent={%ls} aText={%ls} "
-                 "aWarning=%RTbool, preserve=%RTbool\n",
-                 aResultCode, aResultCode, &aIID, aComponent.raw(), aText.raw(), aWarning,
-                 preserve));
+        LogRel(("ERROR [COM]: aRC=%Rhrc (%#08x) aIID={%RTuuid} aComponent={%ls} aText={%ls} "
+                "aWarning=%RTbool, preserve=%RTbool\n",
+                aResultCode, aResultCode, &aIID, bstrComponent.raw(), aText.raw(), aWarning,
+                preserve));
 
     /* these are mandatory, others -- not */
@@ -870,5 +874,5 @@
 
         /* set the current error info and preserve the previous one if any */
-        rc = info->init (aResultCode, aIID, aComponent, aText, curInfo);
+        rc = info->init(aResultCode, aIID, bstrComponent, aText, curInfo);
         if (FAILED(rc)) break;
 
@@ -914,5 +918,5 @@
 
             /* set the current error info and preserve the previous one if any */
-            rc = info->init (aResultCode, aIID, aComponent, aText, curInfo);
+            rc = info->init(aResultCode, aIID, bstrComponent, aText, curInfo);
             if (FAILED(rc)) break;
 
Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 26753)
@@ -302,8 +302,8 @@
     LogFlowThisFuncEnter();
 
-    if (sVersion.isNull())
+    if (sVersion.isEmpty())
         sVersion = VBOX_VERSION_STRING;
     sRevision = RTBldCfgRevision();
-    if (sPackageType.isNull())
+    if (sPackageType.isEmpty())
         sPackageType = VBOX_PACKAGE_STRING;
     LogFlowThisFunc(("Version: %ls, Package: %ls\n", sVersion.raw(), sPackageType.raw()));
@@ -1225,5 +1225,5 @@
     LogFlowThisFunc(("aName=\"%ls\", aMachine={%p}\n", aName, aMachine));
 
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgOutSafeArrayPointerValid(aMachine);
 
@@ -1342,11 +1342,11 @@
 STDMETHODIMP VirtualBox::OpenHardDisk(IN_BSTR aLocation,
                                       AccessMode_T accessMode,
-                                      BOOL aSetImageId, IN_BSTR aImageId,
-                                      BOOL aSetParentId, IN_BSTR aParentId,
+                                      BOOL aSetImageId,
+                                      IN_BSTR aImageId,
+                                      BOOL aSetParentId,
+                                      IN_BSTR aParentId,
                                       IMedium **aHardDisk)
 {
-    CheckComArgNotNull(aLocation);
-    CheckComArgNotNull(aImageId);
-    CheckComArgNotNull(aParentId);
+    CheckComArgStrNotEmptyOrNull(aLocation);
     CheckComArgOutSafeArrayPointerValid(aHardDisk);
 
@@ -1423,5 +1423,5 @@
                                       IMedium **aHardDisk)
 {
-    CheckComArgNotNull(aLocation);
+    CheckComArgStrNotEmptyOrNull(aLocation);
     CheckComArgOutSafeArrayPointerValid(aHardDisk);
 
@@ -1499,5 +1499,5 @@
 STDMETHODIMP VirtualBox::FindDVDImage (IN_BSTR aLocation, IMedium **aDVDImage)
 {
-    CheckComArgNotNull(aLocation);
+    CheckComArgStrNotEmptyOrNull(aLocation);
     CheckComArgOutSafeArrayPointerValid(aDVDImage);
 
@@ -1578,5 +1578,5 @@
                                           IMedium **aFloppyImage)
 {
-    CheckComArgNotNull(aLocation);
+    CheckComArgStrNotEmptyOrNull(aLocation);
     CheckComArgOutSafeArrayPointerValid(aFloppyImage);
 
@@ -1615,5 +1615,5 @@
     };
 
-    CheckComArgNotNull (aType);
+    CheckComArgNotNull(aType);
 
     AutoCaller autoCaller(this);
@@ -1639,6 +1639,6 @@
     {
         const Bstr &typeId = (*it)->id();
-        AssertMsg (!!typeId, ("ID must not be NULL"));
-        if (typeId.compareIgnoreCase (id) == 0)
+        AssertMsg(!typeId.isEmpty(), ("ID must not be NULL"));
+        if (typeId.compare(id, Bstr::CaseInsensitive) == 0)
         {
             (*it).queryInterfaceTo(aType);
@@ -1655,6 +1655,6 @@
 STDMETHODIMP VirtualBox::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL /* aWritable */)
 {
-    CheckComArgNotNull(aName);
-    CheckComArgNotNull(aHostPath);
+    CheckComArgStrNotEmptyOrNull(aName);
+    CheckComArgStrNotEmptyOrNull(aHostPath);
 
     AutoCaller autoCaller(this);
@@ -1666,5 +1666,5 @@
 STDMETHODIMP VirtualBox::RemoveSharedFolder(IN_BSTR aName)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
 
     AutoCaller autoCaller(this);
@@ -1709,5 +1709,5 @@
                                       BSTR *aValue)
 {
-    CheckComArgNotNull(aKey);
+    CheckComArgStrNotEmptyOrNull(aKey);
     CheckComArgNotNull(aValue);
 
@@ -1716,7 +1716,8 @@
 
     /* start with nothing found */
-    Bstr bstrResult("");
-
-    settings::ExtraDataItemsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(Utf8Str(aKey));
+    Utf8Str strKey(aKey);
+    Bstr bstrResult;
+
+    settings::ExtraDataItemsMap::const_iterator it = m->pMainConfigFile->mapExtraDataItems.find(strKey);
     if (it != m->pMainConfigFile->mapExtraDataItems.end())
         // found:
@@ -1735,5 +1736,5 @@
                                       IN_BSTR aValue)
 {
-    CheckComArgNotNull(aKey);
+    CheckComArgStrNotEmptyOrNull(aKey);
 
     AutoCaller autoCaller(this);
@@ -1766,14 +1767,10 @@
         // lock to copy the list of callbacks to invoke
         Bstr error;
-        Bstr bstrValue;
-        if (aValue)
-            bstrValue = aValue;
-        else
-            bstrValue = (const char *)"";
+        Bstr bstrValue(aValue);
 
         if (!onExtraDataCanChange(Guid::Empty, aKey, bstrValue, error))
         {
             const char *sep = error.isEmpty() ? "" : ": ";
-            CBSTR err = error.isNull() ? (CBSTR) L"" : error.raw();
+            CBSTR err = error.raw();
             LogWarningFunc(("Someone vetoed! Change refused%s%ls\n",
                             sep, err));
@@ -1866,7 +1863,7 @@
     LogRel(("remotesession=%s\n", Utf8Str(aMachineId).c_str()));
 
-    CheckComArgNotNull(aMachineId);
+    CheckComArgStrNotEmptyOrNull(aMachineId);
     CheckComArgNotNull(aSession);
-    CheckComArgNotNull(aType);
+    CheckComArgStrNotEmptyOrNull(aType);
     CheckComArgOutSafeArrayPointerValid(aProgress);
 
@@ -4359,5 +4356,5 @@
 STDMETHODIMP VirtualBox::CreateDHCPServer (IN_BSTR aName, IDHCPServer ** aServer)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgNotNull(aServer);
 
@@ -4380,5 +4377,5 @@
 STDMETHODIMP VirtualBox::FindDHCPServerByNetworkName(IN_BSTR aName, IDHCPServer ** aServer)
 {
-    CheckComArgNotNull(aName);
+    CheckComArgStrNotEmptyOrNull(aName);
     CheckComArgNotNull(aServer);
 
@@ -4456,5 +4453,5 @@
 
     ComPtr<IDHCPServer> existing;
-    rc = FindDHCPServerByNetworkName(name.mutableRaw(), existing.asOutParam());
+    rc = FindDHCPServerByNetworkName(name, existing.asOutParam());
     if (SUCCEEDED(rc))
     {
Index: /trunk/src/VBox/Main/generic/NetIf-generic.cpp
===================================================================
--- /trunk/src/VBox/Main/generic/NetIf-generic.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/generic/NetIf-generic.cpp	(revision 26753)
@@ -234,5 +234,5 @@
             return VERR_INVALID_PARAMETER;
         iface->COMGETTER(Name) (ifname.asOutParam());
-        if (ifname.isNull())
+        if (ifname.isEmpty())
             return VERR_INTERNAL_ERROR;
 
Index: /trunk/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/glue/VirtualBoxErrorInfo.cpp	(revision 26753)
@@ -202,5 +202,5 @@
         return NS_ERROR_INVALID_POINTER;
 
-    Utf8Str (mText).cloneTo(aMessage);
+    Utf8Str(mText).cloneTo(aMessage);
     return S_OK;
 }
Index: /trunk/src/VBox/Main/glue/string.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/string.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/glue/string.cpp	(revision 26753)
@@ -4,5 +4,5 @@
  *
  * MS COM / XPCOM Abstraction Layer:
- * Smart string classes definition
+ * UTF-8 and UTF-16 string classes
  */
 
@@ -31,4 +31,10 @@
 {
 
+// BSTR representing a null wide char with 32 bits of length prefix (0);
+// this will work on Windows as well as other platforms where BSTR does
+// not use length prefixes
+const OLECHAR g_achEmptyBstr[3] = { 0, 0, 0 };
+const BSTR g_bstrEmpty = (BSTR)(&g_achEmptyBstr[2]);
+
 /* static */
 const Bstr Bstr::Null; /* default ctor is OK */
@@ -36,4 +42,15 @@
 /* static */
 const Utf8Str Utf8Str::Null; /* default ctor is OK */
+
+#if defined (VBOX_WITH_XPCOM)
+void Utf8Str::cloneTo(char **pstr) const
+{
+    size_t cb = length() + 1;
+    *pstr = (char*)nsMemory::Alloc(cb);
+    if (!*pstr)
+        throw std::bad_alloc();
+    memcpy(*pstr, c_str(), cb);
+}
+#endif
 
 Utf8Str& Utf8Str::toLower()
Index: /trunk/src/VBox/Main/include/VirtualBoxBase.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxBase.h	(revision 26752)
+++ /trunk/src/VBox/Main/include/VirtualBoxBase.h	(revision 26753)
@@ -781,7 +781,10 @@
 class VirtualBoxSupportErrorInfoImplBase
 {
-    static HRESULT setErrorInternal(HRESULT aResultCode, const GUID &aIID,
-                                    const Bstr &aComponent, const Bstr &aText,
-                                    bool aWarning, bool aLogIt);
+    static HRESULT setErrorInternal(HRESULT aResultCode,
+                                    const GUID &aIID,
+                                    const wchar_t *aComponent,
+                                    const Bstr &aText,
+                                    bool aWarning,
+                                    bool aLogIt);
 
 protected:
@@ -910,6 +913,7 @@
     };
 
-    static HRESULT setError(HRESULT aResultCode, const GUID &aIID,
-                            const Bstr &aComponent,
+    static HRESULT setError(HRESULT aResultCode,
+                            const GUID &aIID,
+                            const wchar_t *aComponent,
                             const Bstr &aText,
                             bool aLogIt = true)
@@ -919,6 +923,7 @@
     }
 
-    static HRESULT setWarning(HRESULT aResultCode, const GUID &aIID,
-                              const Bstr &aComponent,
+    static HRESULT setWarning(HRESULT aResultCode,
+                              const GUID &aIID,
+                              const wchar_t *aComponent,
                               const Bstr &aText)
     {
@@ -927,6 +932,7 @@
     }
 
-    static HRESULT setError(HRESULT aResultCode, const GUID &aIID,
-                            const Bstr &aComponent,
+    static HRESULT setError(HRESULT aResultCode,
+                            const GUID &aIID,
+                            const wchar_t *aComponent,
                             const char *aText, va_list aArgs, bool aLogIt = true)
     {
@@ -936,6 +942,7 @@
     }
 
-    static HRESULT setWarning(HRESULT aResultCode, const GUID &aIID,
-                              const Bstr &aComponent,
+    static HRESULT setWarning(HRESULT aResultCode,
+                              const GUID &aIID,
+                              const wchar_t *aComponent,
                               const char *aText, va_list aArgs)
     {
@@ -1061,6 +1068,10 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(
-            aResultCode, aIID, aComponent, aText, args, true /* aLogIt */);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
+                                                                  aIID,
+                                                                  aComponent,
+                                                                  aText,
+                                                                  args,
+                                                                  true /* aLogIt */);
         va_end(args);
         return rc;
@@ -1115,6 +1126,10 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(
-            aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args, true /* aLogIt */);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
+                                                                  COM_IIDOF(I),
+                                                                  C::getComponentName(),
+                                                                  aText,
+                                                                  args,
+                                                                  true /* aLogIt */);
         va_end(args);
         return rc;
@@ -1134,6 +1149,9 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(
-            aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
+                                                                    COM_IIDOF(I),
+                                                                    C::getComponentName(),
+                                                                    aText,
+                                                                    args);
         va_end(args);
         return rc;
@@ -1152,6 +1170,10 @@
                              va_list aArgs)
     {
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(
-            aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs, true /* aLogIt */);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
+                                                                  COM_IIDOF(I),
+                                                                  C::getComponentName(),
+                                                                  aText,
+                                                                  aArgs,
+                                                                  true /* aLogIt */);
         return rc;
     }
@@ -1169,6 +1191,9 @@
                                va_list aArgs)
     {
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(
-            aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
+                                                                    COM_IIDOF(I),
+                                                                    C::getComponentName(),
+                                                                    aText,
+                                                                    aArgs);
         return rc;
     }
@@ -1188,6 +1213,10 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(
-            aResultCode, aIID, C::getComponentName(), aText, args, true /* aLogIt */);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
+                                                                  aIID,
+                                                                  C::getComponentName(),
+                                                                  aText,
+                                                                  args,
+                                                                  true /* aLogIt */);
         va_end(args);
         return rc;
@@ -1208,6 +1237,9 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(
-            aResultCode, aIID, C::getComponentName(), aText, args);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
+                                                                    aIID,
+                                                                    C::getComponentName(),
+                                                                    aText,
+                                                                    args);
         va_end(args);
         return rc;
@@ -1225,6 +1257,10 @@
         va_list args;
         va_start(args, aText);
-        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(
-            aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args, false /* aLogIt */);
+        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
+                                                                  COM_IIDOF(I),
+                                                                  C::getComponentName(),
+                                                                  aText,
+                                                                  args,
+                                                                  false /* aLogIt */);
         va_end(args);
         return rc;
Index: /trunk/src/VBox/Main/win/NetIf-win.cpp
===================================================================
--- /trunk/src/VBox/Main/win/NetIf-win.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/win/NetIf-win.cpp	(revision 26753)
@@ -908,8 +908,5 @@
     if(hr == S_OK)
     {
-        size_t cUnicodeName = wcslen(lpszName) + 1;
-        size_t uniLen = (cUnicodeName * 2 + sizeof (OLECHAR) - 1) / sizeof (OLECHAR);
-        Bstr name (uniLen + 1 /* extra zero */);
-        wcscpy((wchar_t *) name.mutableRaw(), lpszName);
+        Bstr name(lpszName);
 
         hr = pncc->GetInstanceGuid(&IfGuid);
Index: /trunk/src/VBox/Main/win/svcmain.cpp
===================================================================
--- /trunk/src/VBox/Main/win/svcmain.cpp	(revision 26752)
+++ /trunk/src/VBox/Main/win/svcmain.cpp	(revision 26753)
@@ -231,11 +231,5 @@
 
                 if (*lpszToken != NULL)
-                {
-                    Bstr str (lpszToken);
-                    LPCTSTR lpszToken2 = FindOneOf(lpszToken, szTokens);
-                    if (lpszToken2)
-                        str.mutableRaw()[lpszToken2 - lpszToken] = '\0';
                     pipeName = Utf8Str(lpszToken);
-                }
             }
 
