+    // strtok() doesn't return empty tokens, all other modes do
+    bool allowEmpty = m_mode != wxTOKEN_STRTOK;
+
+    wxString token;
+    do
+    {
+        if ( !HasMoreTokens() )
+        {
+            break;
+        }
+        // find the end of this token
+        size_t pos = m_string.find_first_of(m_delims);
+
+        // and the start of the next one
+        if ( pos == wxString::npos )
+        {
+            // no more delimiters, the token is everything till the end of
+            // string
+            token = m_string;
+
+            m_pos += m_string.length();
+            m_string.clear();
+
+            // no more tokens in this string, even in wxTOKEN_RET_EMPTY_ALL
+            // mode (we will return the trailing one right now in this case)
+            m_hasMore = FALSE;
+        }
+        else
+        {
+            size_t pos2 = pos + 1;
+
+            // in wxTOKEN_RET_DELIMS mode we return the delimiter character
+            // with token
+            token = wxString(m_string, m_mode == wxTOKEN_RET_DELIMS ? pos2
+                                                                    : pos);
+
+            // remove token with the following it delimiter from string
+            m_string.erase(0, pos2);
+
+            // keep track of the position in the original string too
+            m_pos += pos2;
+        }
+    }
+    while ( !allowEmpty && token.empty() );
+
+    return token;