Index: /trunk/include/VBox/com/string.h
===================================================================
--- /trunk/include/VBox/com/string.h	(revision 60408)
+++ /trunk/include/VBox/com/string.h	(revision 60409)
@@ -230,4 +230,53 @@
 
     /**
+     * Compares this string to an UTF-8 C style string.
+     *
+     * @retval  0 if equal
+     * @retval -1 if this string is smaller than the UTF-8 one.
+     * @retval  1 if the UTF-8 string is smaller than this.
+     *
+     * @param   a_pszRight  The string to compare with.
+     * @param   a_enmCase   Whether comparison should be case-sensitive.
+     */
+    int compareUtf8(const char *a_pszRight, CaseSensitivity a_enmCase = CaseSensitive) const;
+
+    /** Java style compare method.
+     * @returns true if @a a_pszRight equals this string.
+     * @param   a_pszRight The (UTF-8) string to compare with. */
+    bool equals(const char *a_pszRight) const           { return compareUtf8(a_pszRight, CaseSensitive) == 0; }
+
+    /** Java style case-insensitive compare method.
+     * @returns true if @a a_pszRight equals this string.
+     * @param   a_pszRight The (UTF-8) string to compare with. */
+    bool equalsIgnoreCase(const char *a_pszRight) const { return compareUtf8(a_pszRight, CaseInsensitive) == 0; }
+
+    /** Java style compare method.
+     * @returns true if @a a_rThat equals this string.
+     * @param   a_rThat     The other Bstr instance to compare with. */
+    bool equals(const Bstr &a_rThat) const              { return compare(a_rThat.m_bstr, CaseSensitive) == 0; }
+    /** Java style case-insensitive compare method.
+     * @returns true if @a a_rThat equals this string.
+     * @param   a_rThat     The other Bstr instance to compare with. */
+    bool equalsIgnoreCase(const Bstr &a_rThat) const    { return compare(a_rThat.m_bstr, CaseInsensitive) == 0; }
+
+    /** Java style compare method.
+     * @returns true if @a a_pThat equals this string.
+     * @param   a_pThat    The native const BSTR to compare with. */
+    bool equals(CBSTR a_pThat) const                    { return compare(a_pThat, CaseSensitive) == 0; }
+    /** Java style case-insensitive compare method.
+     * @returns true if @a a_pThat equals this string.
+     * @param   a_pThat    The native const BSTR to compare with. */
+    bool equalsIgnoreCase(CBSTR a_pThat) const          { return compare(a_pThat, CaseInsensitive) == 0; }
+
+    /** Java style compare method.
+     * @returns true if @a a_pThat equals this string.
+     * @param   a_pThat    The native BSTR to compare with. */
+    bool equals(BSTR a_pThat) const                     { return compare(a_pThat, CaseSensitive) == 0; }
+    /** Java style case-insensitive compare method.
+     * @returns true if @a a_pThat equals this string.
+     * @param   a_pThat    The native BSTR to compare with. */
+    bool equalsIgnoreCase(BSTR a_pThat) const           { return compare(a_pThat, CaseInsensitive) == 0; }
+
+    /**
      * Returns true if the member string has no length.
      * This is true for instances created from both NULL and "" input strings.
Index: /trunk/src/VBox/Main/glue/string.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/string.cpp	(revision 60408)
+++ /trunk/src/VBox/Main/glue/string.cpp	(revision 60409)
@@ -21,4 +21,6 @@
 #include <iprt/path.h>
 #include <iprt/log.h>
+#include <iprt/string.h>
+#include <iprt/uni.h>
 
 namespace com
@@ -71,4 +73,48 @@
 }
 
+int Bstr::compareUtf8(const char *a_pszRight, CaseSensitivity a_enmCase /*= CaseSensitive*/) const
+{
+    PCRTUTF16 pwszLeft = m_bstr;
+
+    /*
+     * Special case for null/empty strings.  Unlike RTUtf16Cmp we
+     * treat null and empty equally.
+     */
+    if (!pwszLeft)
+        return !a_pszRight || *a_pszRight == '\0' ? 0 : -1;
+    if (!a_pszRight)
+        return *pwszLeft == '\0'                  ? 0 :  1;
+
+    /*
+     * Compare with a UTF-8 string by enumerating them char by char.
+     */
+    for (;;)
+    {
+        RTUNICP ucLeft;
+        int rc = RTUtf16GetCpEx(&pwszLeft, &ucLeft);
+        AssertRCReturn(rc, 1);
+
+        RTUNICP ucRight;
+        rc = RTStrGetCpEx(&a_pszRight, &ucRight);
+        AssertRCReturn(rc, -1);
+        if (ucLeft == ucRight)
+        {
+            if (ucLeft)
+                continue;
+            return 0;
+        }
+
+        if (a_enmCase == CaseInsensitive)
+        {
+            if (RTUniCpToUpper(ucLeft) == RTUniCpToUpper(ucRight))
+                continue;
+            if (RTUniCpToLower(ucLeft) == RTUniCpToLower(ucRight))
+                continue;
+        }
+
+        return ucLeft < ucRight ? -1 : 1;
+    }
+}
+
 
 /* static */
