/////////////////////////////////////////////////////////////////////////////
-// Name:        string.cpp
+// Name:        src/common/string.cpp
 // Purpose:     wxString class
 // Author:      Vadim Zeitlin, Ryan Norton
 // Modified by:
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-  #pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
-  #include "wx/defs.h"
-  #include "wx/string.h"
-  #include "wx/intl.h"
-  #include "wx/thread.h"
+    #include "wx/string.h"
+    #include "wx/intl.h"
+    #include "wx/thread.h"
 #endif
 
 #include <ctype.h>
 #include <stdlib.h>
 
 #ifdef __SALFORDC__
-  #include <clib.h>
+    #include <clib.h>
 #endif
 
 // allocating extra space for each string consumes more memory but speeds up
     {
         if ( nLength == npos )
         {
-            nLength = (size_t)-1;
-        }
-        else if ( nLength == length() )
-        {
-            // this is important to avoid copying the string in cMB2WC: we're
-            // already NUL-terminated so we can pass this NUL with the data
-            nLength++;
+            nLength = wxNO_LEN;
         }
 
         size_t nLenWide;
     {
         if ( nLength == npos )
         {
-            nLength = (size_t)-1;
-        }
-        else if ( nLength == length() )
-        {
-            // this is important to avoid copying the string in cMB2WC: we're
-            // already NUL-terminated so we can pass this NUL with the data
-            nLength++;
+            nLength = wxNO_LEN;
         }
 
         size_t nLenMB;
     return true;
 }
 
+
+// check that the string ends with suffix and return the rest of it in the
+// provided pointer if it is not NULL, otherwise return false
+bool wxString::EndsWith(const wxChar *suffix, wxString *rest) const
+{
+    wxASSERT_MSG( suffix, _T("invalid parameter in wxString::EndssWith") );
+
+    int start = length() - wxStrlen(suffix);
+    if ( start < 0 || wxStrcmp(c_str() + start, suffix) != 0 )
+        return false;
+
+    if ( rest )
+    {
+        // put the rest of the string into provided pointer
+        rest->assign(*this, 0, start);
+    }
+
+    return true;
+}
+
+
 // extract nCount last (rightmost) characters
 wxString wxString::Right(size_t nCount) const
 {
 #if wxUSE_THREADS
   // need a critical section to protect access to gs_compareFunction and
   // gs_sortAscending variables
-  static wxCriticalSection *gs_critsectStringSort = NULL;
-
-  // call this before the value of the global sort vars is changed/after
-  // you're finished with them
-  #define START_SORT()     wxASSERT( !gs_critsectStringSort );                \
-                           gs_critsectStringSort = new wxCriticalSection;     \
-                           gs_critsectStringSort->Enter()
-  #define END_SORT()       gs_critsectStringSort->Leave();                    \
-                           delete gs_critsectStringSort;                      \
-                           gs_critsectStringSort = NULL
-#else // !threads
-  #define START_SORT()
-  #define END_SORT()
+  static wxCriticalSection gs_critsectStringSort;
 #endif // wxUSE_THREADS
 
 // function to use for string comparaison
 // sort array elements using passed comparaison function
 void wxArrayString::Sort(CompareFunction compareFunction)
 {
-  START_SORT();
+  wxCRIT_SECT_LOCKER(lockCmpFunc, gs_critsectStringSort);
 
   wxASSERT( !gs_compareFunction );  // must have been reset to NULL
   gs_compareFunction = compareFunction;
 
   // reset it to NULL so that Sort(bool) will work the next time
   gs_compareFunction = NULL;
-
-  END_SORT();
 }
 
 extern "C"