+  return true;
+}
+
+// ---------------------------------------------------------------------------
+// simple sub-string extraction
+// ---------------------------------------------------------------------------
+
+// helper function: clone the data attached to this string
+bool wxStringBase::AllocCopy(wxString& dest, int nCopyLen, int nCopyIndex) const
+{
+  if ( nCopyLen == 0 ) {
+    dest.Init();
+  }
+  else {
+    if ( !dest.AllocBuffer(nCopyLen) ) {
+      // allocation failure handled by caller
+      return false;
+    }
+    memcpy(dest.m_pchData, m_pchData + nCopyIndex, nCopyLen*sizeof(wxChar));
+  }
+  return true;
+}
+
+#endif // !wxUSE_STL
+
+#if !wxUSE_STL || !defined(HAVE_STD_STRING_COMPARE)
+
+#if !wxUSE_STL
+    #define STRINGCLASS wxStringBase
+#else
+    #define STRINGCLASS wxString
+#endif
+
+static inline int wxDoCmp(const wxChar* s1, size_t l1,
+                          const wxChar* s2, size_t l2)
+{
+    if( l1 == l2 )
+        return wxTmemcmp(s1, s2, l1);
+    else if( l1 < l2 )
+    {
+        int ret = wxTmemcmp(s1, s2, l1);
+        return ret == 0 ? -1 : ret;
+    }
+    else
+    {
+        int ret = wxTmemcmp(s1, s2, l2);
+        return ret == 0 ? +1 : ret;
+    }
+}
+
+int STRINGCLASS::compare(const wxStringBase& str) const
+{
+    return ::wxDoCmp(data(), length(), str.data(), str.length());
+}
+
+int STRINGCLASS::compare(size_t nStart, size_t nLen,
+                         const wxStringBase& str) const
+{
+    wxASSERT(nStart <= length());
+    size_type strLen = length() - nStart;
+    nLen = strLen < nLen ? strLen : nLen;
+    return ::wxDoCmp(data() + nStart, nLen, str.data(), str.length());
+}
+
+int STRINGCLASS::compare(size_t nStart, size_t nLen,
+                         const wxStringBase& str,
+                         size_t nStart2, size_t nLen2) const
+{
+    wxASSERT(nStart <= length());
+    wxASSERT(nStart2 <= str.length());
+    size_type strLen  =     length() - nStart,
+              strLen2 = str.length() - nStart2;
+    nLen  = strLen  < nLen  ? strLen  : nLen;
+    nLen2 = strLen2 < nLen2 ? strLen2 : nLen2;
+    return ::wxDoCmp(data() + nStart, nLen, str.data() + nStart2, nLen2);
+}
+
+int STRINGCLASS::compare(const wxChar* sz) const
+{
+    size_t nLen = wxStrlen(sz);
+    return ::wxDoCmp(data(), length(), sz, nLen);
+}
+
+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 and conversion
+// ---------------------------------------------------------------------------
+
+#if wxUSE_UNICODE
+
+// from multibyte string
+wxString::wxString(const char *psz, const wxMBConv& conv, size_t nLength)
+{
+    // anything to do?
+    if ( psz && nLength != 0 )
+    {
+        if ( nLength == npos )
+        {
+            nLength = wxNO_LEN;
+        }
+
+        size_t nLenWide;
+        wxWCharBuffer wbuf = conv.cMB2WC(psz, nLength, &nLenWide);
+
+        if ( nLenWide )
+            assign(wbuf, nLenWide);
+    }
+}
+
+//Convert wxString in Unicode mode to a multi-byte string
+const wxCharBuffer wxString::mb_str(const wxMBConv& conv) const
+{
+    return conv.cWC2MB(c_str(), length() + 1 /* size, not length */, NULL);
+}
+
+#else // ANSI
+
+#if wxUSE_WCHAR_T
+
+// from wide string
+wxString::wxString(const wchar_t *pwz, const wxMBConv& conv, size_t nLength)
+{
+    // anything to do?
+    if ( pwz && nLength != 0 )
+    {
+        if ( nLength == npos )
+        {
+            nLength = wxNO_LEN;
+        }
+
+        size_t nLenMB;
+        wxCharBuffer buf = conv.cWC2MB(pwz, nLength, &nLenMB);
+
+        if ( nLenMB )
+            assign(buf, nLenMB);
+    }
+}
+
+//Converts this string to a wide character string if unicode
+//mode is not enabled and wxUSE_WCHAR_T is enabled
+const wxWCharBuffer wxString::wc_str(const wxMBConv& conv) const
+{
+    return conv.cMB2WC(c_str(), length() + 1 /* size, not length */, NULL);
+}
+
+#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();
+}
+
+#if !wxUSE_STL
+// get the pointer to writable buffer of (at least) nLen bytes
+wxChar *wxString::GetWriteBuf(size_t nLen)
+{
+  if ( !AllocBeforeWrite(nLen) ) {
+    // allocation failure handled by caller
+    return NULL;
+  }
+
+  wxASSERT( GetStringData()->nRefs == 1 );
+  GetStringData()->Validate(false);
+
+  return m_pchData;
+}
+
+// put string back in a reasonable state after GetWriteBuf
+void wxString::UngetWriteBuf()
+{
+  GetStringData()->nDataLength = wxStrlen(m_pchData);
+  GetStringData()->Validate(true);
+}
+
+void wxString::UngetWriteBuf(size_t nLen)
+{
+  GetStringData()->nDataLength = nLen;
+  GetStringData()->Validate(true);
+}
+#endif
+
+// ---------------------------------------------------------------------------
+// data access
+// ---------------------------------------------------------------------------
+
+// all functions are inline in string.h
+
+// ---------------------------------------------------------------------------
+// assignment operators
+// ---------------------------------------------------------------------------
+
+#if !wxUSE_UNICODE
+
+// same as 'signed char' variant
+wxString& wxString::operator=(const unsigned char* psz)
+{
+  *this = (const char *)psz;
+  return *this;