+    size_t nLen = wxStrlen(sz);
+    return ::wxDoCmp(data(), length(), sz, nLen);
+}
+
+#endif
+
+int STRINGCLASS::compare(size_t nStart, size_t nLen,
+                         const wxChar* sz, size_t nCount) const
+{
+    wxASSERT(nStart <= length());
+    size_type strLen = length() - nStart;
+    nLen = strLen < nLen ? strLen : nLen;
+    if( nCount == npos )
+        nCount = wxStrlen(sz);
+
+    return ::wxDoCmp(data() + nStart, nLen, sz, nCount);
+}
+
+#undef STRINGCLASS
+
+#endif // !wxUSE_STL || !defined(HAVE_STD_STRING_COMPARE)
+
+// ===========================================================================
+// wxString class core
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// construction
+// ---------------------------------------------------------------------------
+
+#if wxUSE_UNICODE
+
+// from multibyte string
+wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
+{
+    // first get the size of the buffer we need
+    size_t nLen;
+    if ( psz )
+    {
+        // calculate the needed size ourselves or use the provided one
+        nLen = nLength == npos ? conv.MB2WC(NULL, psz, 0) : nLength;
+    }
+    else
+    {
+        // nothing to convert
+        nLen = 0;
+    }
+
+    // anything to do?
+    if ( (nLen != 0) && (nLen != (size_t)-1) )
+    {
+        if ( !Alloc(nLen) )
+        {
+            wxFAIL_MSG( _T("out of memory in wxString::wxString") );
+        }
+        else
+        {
+            wxWCharBuffer buf(nLen + 1);
+            // MB2WC wants the buffer size, not the string length hence +1
+            nLen = conv.MB2WC(buf.data(), psz, nLen + 1);
+
+            if ( nLen != (size_t)-1 )
+            {
+                // initialized ok, set the real length as nLength specified by
+                // the caller could be greater than the real string length
+                assign(buf.data(), nLen);
+                return;
+            }
+            //else: the conversion failed -- leave the string empty (what else?)
+        }
+    }
+}
+
+#else // ANSI
+
+#if wxUSE_WCHAR_T
+// from wide string
+wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
+{
+    // first get the size of the buffer we need
+    size_t nLen;
+    if ( pwz )
+    {
+        // calculate the needed size ourselves or use the provided one
+        nLen = nLength == npos ? conv.WC2MB(NULL, pwz, 0) : nLength;
+    }
+    else
+    {
+        // nothing to convert
+        nLen = 0;
+    }
+
+    // anything to do?
+    if ( (nLen != 0) && (nLen != (size_t)-1) )
+    {
+        if ( !Alloc(nLen) )
+        {
+            wxFAIL_MSG( _T("out of memory in wxString::wxString") );
+        }
+        else
+        {
+            wxCharBuffer buf(nLen);
+            // WC2MB wants the buffer size, not the string length
+            if ( conv.WC2MB(buf.data(), pwz, nLen + 1) != (size_t)-1 )
+            {
+                // initialized ok
+                assign(buf.data(), nLen);
+                return;
+            }
+            //else: the conversion failed -- leave the string empty (what else?)
+        }
+    }
+
+    // leave empty
+}
+#endif // wxUSE_WCHAR_T
+
+#endif // Unicode/ANSI
+
+// shrink to minimal size (releasing extra memory)
+bool wxString::Shrink()
+{
+  wxString tmp(begin(), end());
+  swap(tmp);
+  return tmp.length() == length();