+// ----------------------------------------------------------------------------
+// misc other operations
+// ----------------------------------------------------------------------------
+
+// returns true if the string matches the pattern which may contain '*' and
+// '?' metacharacters (as usual, '?' matches any character and '*' any number
+// of them)
+bool wxString::Matches(const wxString& mask) const
+{
+    // I disable this code as it doesn't seem to be faster (in fact, it seems
+    // to be much slower) than the old, hand-written code below and using it
+    // here requires always linking with libregex even if the user code doesn't
+    // use it
+#if 0 // wxUSE_REGEX
+    // first translate the shell-like mask into a regex
+    wxString pattern;
+    pattern.reserve(wxStrlen(pszMask));
+
+    pattern += _T('^');
+    while ( *pszMask )
+    {
+        switch ( *pszMask )
+        {
+            case _T('?'):
+                pattern += _T('.');
+                break;
+
+            case _T('*'):
+                pattern += _T(".*");
+                break;
+
+            case _T('^'):
+            case _T('.'):
+            case _T('$'):
+            case _T('('):
+            case _T(')'):
+            case _T('|'):
+            case _T('+'):
+            case _T('\\'):
+                // these characters are special in a RE, quote them
+                // (however note that we don't quote '[' and ']' to allow
+                // using them for Unix shell like matching)
+                pattern += _T('\\');
+                // fall through
+
+            default:
+                pattern += *pszMask;
+        }
+
+        pszMask++;
+    }
+    pattern += _T('$');
+
+    // and now use it
+    return wxRegEx(pattern, wxRE_NOSUB | wxRE_EXTENDED).Matches(c_str());
+#else // !wxUSE_REGEX
+  // TODO: this is, of course, awfully inefficient...
+
+  // FIXME-UTF8: implement using iterators, remove #if
+#if wxUSE_UNICODE_UTF8
+  wxWCharBuffer maskBuf = mask.wc_str();
+  wxWCharBuffer txtBuf = wc_str();
+  const wxChar *pszMask = maskBuf.data();
+  const wxChar *pszTxt = txtBuf.data();
+#else
+  const wxChar *pszMask = mask.wx_str();
+  // the char currently being checked
+  const wxChar *pszTxt = wx_str();
+#endif
+
+  // the last location where '*' matched
+  const wxChar *pszLastStarInText = NULL;
+  const wxChar *pszLastStarInMask = NULL;
+
+match:
+  for ( ; *pszMask != wxT('\0'); pszMask++, pszTxt++ ) {
+    switch ( *pszMask ) {
+      case wxT('?'):
+        if ( *pszTxt == wxT('\0') )
+          return false;
+
+        // pszTxt and pszMask will be incremented in the loop statement
+
+        break;
+
+      case wxT('*'):
+        {
+          // remember where we started to be able to backtrack later
+          pszLastStarInText = pszTxt;
+          pszLastStarInMask = pszMask;
+
+          // ignore special chars immediately following this one
+          // (should this be an error?)
+          while ( *pszMask == wxT('*') || *pszMask == wxT('?') )
+            pszMask++;
+
+          // if there is nothing more, match
+          if ( *pszMask == wxT('\0') )
+            return true;
+
+          // are there any other metacharacters in the mask?
+          size_t uiLenMask;
+          const wxChar *pEndMask = wxStrpbrk(pszMask, wxT("*?"));
+
+          if ( pEndMask != NULL ) {
+            // we have to match the string between two metachars
+            uiLenMask = pEndMask - pszMask;
+          }
+          else {
+            // we have to match the remainder of the string
+            uiLenMask = wxStrlen(pszMask);
+          }
+
+          wxString strToMatch(pszMask, uiLenMask);
+          const wxChar* pMatch = wxStrstr(pszTxt, strToMatch);
+          if ( pMatch == NULL )
+            return false;
+
+          // -1 to compensate "++" in the loop
+          pszTxt = pMatch + uiLenMask - 1;
+          pszMask += uiLenMask - 1;
+        }
+        break;