-    AddToMimeData (strMimeType, strIcon, NULL, sExts, strDesc, TRUE);
-}
-
-void wxMimeTypesManagerImpl::AddMailcapInfo(const wxString& strType,
-                                            const wxString& strOpenCmd,
-                                            const wxString& strPrintCmd,
-                                            const wxString& strTest,
-                                            const wxString& strDesc)
-{
-    InitIfNeeded();
-
-    wxMimeTypeCommands *entry = new wxMimeTypeCommands;
-    entry->Add(wxT("open=")  + strOpenCmd);
-    entry->Add(wxT("print=") + strPrintCmd);
-    entry->Add(wxT("test=")  + strTest);
-
-    wxString strIcon;
-    wxArrayString strExtensions;
-
-    AddToMimeData (strType, strIcon, entry, strExtensions, strDesc, TRUE);
-
-}
-
-bool wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
-{
-    wxLogTrace(TRACE_MIME, wxT("--- Parsing mime.types file '%s' ---"),
-               strFileName.c_str());
-
-    wxTextFile file(strFileName);
-#if defined(__WXGTK20__) && wxUSE_UNICODE
-    if ( !file.Open( wxConvUTF8) )
-#else
-    if ( !file.Open() )
-#endif
-        return FALSE;
-
-    // the information we extract
-    wxString strMimeType, strDesc, strExtensions;
-
-    size_t nLineCount = file.GetLineCount();
-    const wxChar *pc = NULL;
-    for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
-    {
-        if ( pc == NULL ) {
-            // now we're at the start of the line
-            pc = file[nLine].c_str();
-        }
-        else {
-            // we didn't finish with the previous line yet
-            nLine--;
-        }
-
-        // skip whitespace
-        while ( wxIsspace(*pc) )
-            pc++;
-
-        // comment or blank line?
-        if ( *pc == wxT('#') || !*pc ) {
-            // skip the whole line
-            pc = NULL;
-            continue;
-        }
-
-        // detect file format
-        const wxChar *pEqualSign = wxStrchr(pc, wxT('='));
-        if ( pEqualSign == NULL ) {
-            // brief format
-            // ------------
-
-            // first field is mime type
-            for ( strMimeType.Empty(); !wxIsspace(*pc) && *pc != wxT('\0'); pc++ ) {
-                strMimeType += *pc;
-            }
-
-            // skip whitespace
-            while ( wxIsspace(*pc) )
-                pc++;
-
-            // take all the rest of the string
-            strExtensions = pc;
-
-            // no description...
-            strDesc.Empty();
-        }
-        else {
-            // expanded format
-            // ---------------
-
-            // the string on the left of '=' is the field name
-            wxString strLHS(pc, pEqualSign - pc);
-
-            // eat whitespace
-            for ( pc = pEqualSign + 1; wxIsspace(*pc); pc++ )
-              ;
-
-            const wxChar *pEnd;
-            if ( *pc == wxT('"') ) {
-                // the string is quoted and ends at the matching quote
-                pEnd = wxStrchr(++pc, wxT('"'));
-                if ( pEnd == NULL ) {
-                    wxLogWarning(_("Mime.types file %s, line %d: unterminated "
-                                   "quoted string."),
-                                 strFileName.c_str(), nLine + 1);
-                }
-            }
-            else {
-                // unquoted string ends at the first space or at the end of
-                // line
-                for ( pEnd = pc; *pEnd && !wxIsspace(*pEnd); pEnd++ )
-                  ;
-            }
-
-            // now we have the RHS (field value)
-            wxString strRHS(pc, pEnd - pc);
-
-            // check what follows this entry
-            if ( *pEnd == wxT('"') ) {
-                // skip this quote
-                pEnd++;
-            }
-
-            for ( pc = pEnd; wxIsspace(*pc); pc++ )
-              ;
-
-            // if there is something left, it may be either a '\\' to continue
-            // the line or the next field of the same entry
-            bool entryEnded = *pc == wxT('\0'),
-                 nextFieldOnSameLine = FALSE;
-            if ( !entryEnded ) {
-                nextFieldOnSameLine = ((*pc != wxT('\\')) || (pc[1] != wxT('\0')));
-            }
-
-            // now see what we got
-            if ( strLHS == wxT("type") ) {
-                strMimeType = strRHS;
-            }
-            else if ( strLHS.StartsWith(wxT("desc")) ) {
-                strDesc = strRHS;
-            }
-            else if ( strLHS == wxT("exts") ) {
-                strExtensions = strRHS;
-            }
-            else {
-                // this one is simply ignored: it usually refers to Netscape
-                // built in icons which are useless for us anyhow
-                if ( strLHS != _T("icon") )
-                {
-                    // This crashes for some reason in wcslen() in libc. RR.
-                    // wxLogWarning(_("Unknown field in file %s, line %d: '%s'."),
-                    //                strFileName.c_str(), nLine + 1, strLHS.c_str());
-                }
-            }
-
-            if ( !entryEnded ) {
-                if ( !nextFieldOnSameLine )
-                    pc = NULL;
-                //else: don't reset it
-
-                // as we don't reset strMimeType, the next field in this entry
-                // will be interpreted correctly.
-
-                continue;
-            }
-        }
-
-        // depending on the format (Mosaic or Netscape) either space or comma
-        // is used to separate the extensions
-        strExtensions.Replace(wxT(","), wxT(" "));
-
-        // also deal with the leading dot
-        if ( !strExtensions.empty() && strExtensions[0u] == wxT('.') )
-        {
-            strExtensions.erase(0, 1);
-        }
-
-        wxLogTrace(TRACE_MIME, wxT("mime.types: '%s' => '%s' (%s)"),
-                   strExtensions.c_str(),
-                   strMimeType.c_str(),
-                   strDesc.c_str());
-
-        AddMimeTypeInfo(strMimeType, strExtensions, strDesc);
-
-        // finished with this line
-        pc = NULL;
-    }
-
-    return TRUE;
-}
-
-// ----------------------------------------------------------------------------
-// UNIX mailcap files parsing
-// ----------------------------------------------------------------------------
-
-// the data for a single MIME type
-struct MailcapLineData
-{
-    // field values
-    wxString type,
-             cmdOpen,
-             test,
-             icon,
-             desc;
-
-    wxArrayString verbs,
-                  commands;
-
-    // flags
-    bool testfailed,
-         needsterminal,
-         copiousoutput;
-
-    MailcapLineData() { testfailed = needsterminal = copiousoutput = FALSE; }
-};
-
-// process a non-standard (i.e. not the first or second one) mailcap field
-bool
-wxMimeTypesManagerImpl::ProcessOtherMailcapField(MailcapLineData& data,
-                                                 const wxString& curField)
-{
-    if ( curField.empty() )
-    {
-        // we don't care
-        return TRUE;
-    }
-
-    // is this something of the form foo=bar?
-    const wxChar *pEq = wxStrchr(curField, wxT('='));
-    if ( pEq != NULL )
-    {
-        // split "LHS = RHS" in 2
-        wxString lhs = curField.BeforeFirst(wxT('=')),
-                 rhs = curField.AfterFirst(wxT('='));
-
-        lhs.Trim(TRUE);     // from right
-        rhs.Trim(FALSE);    // from left
-
-        // it might be quoted
-        if ( !rhs.empty() && rhs[0u] == wxT('"') && rhs.Last() == wxT('"') )
-        {
-            rhs = rhs.Mid(1, rhs.length() - 2);
-        }
-
-        // is it a command verb or something else?
-        if ( lhs == wxT("test") )
-        {
-            if ( wxSystem(rhs) == 0 )
-            {
-                // ok, test passed
-                wxLogTrace(TRACE_MIME_TEST,
-                           wxT("Test '%s' for mime type '%s' succeeded."),
-                           rhs.c_str(), data.type.c_str());
-
-            }
-            else
-            {
-                wxLogTrace(TRACE_MIME_TEST,
-                           wxT("Test '%s' for mime type '%s' failed, skipping."),
-                           rhs.c_str(), data.type.c_str());
-
-                data.testfailed = TRUE;
-            }
-        }
-        else if ( lhs == wxT("desc") )
-        {
-            data.desc = rhs;
-        }
-        else if ( lhs == wxT("x11-bitmap") )
-        {
-            data.icon = rhs;
-        }
-        else if ( lhs == wxT("notes") )
-        {
-            // ignore
-        }
-        else // not a (recognized) special case, must be a verb (e.g. "print")
-        {
-            data.verbs.Add(lhs);
-            data.commands.Add(rhs);
-        }
-    }
-    else // '=' not found
-    {
-        // so it must be a simple flag
-        if ( curField == wxT("needsterminal") )
-        {
-            data.needsterminal = TRUE;
-        }
-        else if ( curField == wxT("copiousoutput"))
-        {
-            // copiousoutput impies that the viewer is a console program
-            data.needsterminal =
-            data.copiousoutput = TRUE;
-        }
-        else if ( !IsKnownUnimportantField(curField) )
-        {
-            return FALSE;
-        }
-    }
-
-    return TRUE;
-}
-
-bool wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName,
-                                         bool fallback)
-{
-    wxLogTrace(TRACE_MIME, wxT("--- Parsing mailcap file '%s' ---"),
-               strFileName.c_str());
-
-    wxTextFile file(strFileName);
-#if defined(__WXGTK20__) && wxUSE_UNICODE
-    if ( !file.Open( wxConvUTF8) )
-#else
-    if ( !file.Open() )
-#endif
-        return FALSE;
-
-    // indices of MIME types (in m_aTypes) we already found in this file
-    //
-    // (see the comments near the end of function for the reason we need this)
-    wxArrayInt aIndicesSeenHere;
-
-    // accumulator for the current field
-    wxString curField;
-    curField.reserve(1024);
-
-    size_t nLineCount = file.GetLineCount();
-    for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
-    {
-        // now we're at the start of the line
-        const wxChar *pc = file[nLine].c_str();
-
-        // skip whitespace
-        while ( wxIsspace(*pc) )
-            pc++;
-
-        // comment or empty string?
-        if ( *pc == wxT('#') || *pc == wxT('\0') )
-            continue;
-
-        // no, do parse
-        // ------------
-
-        // what field are we currently in? The first 2 are fixed and there may
-        // be an arbitrary number of other fields parsed by
-        // ProcessOtherMailcapField()
-        //
-        // the first field is the MIME type
-        enum
-        {
-            Field_Type,
-            Field_OpenCmd,
-            Field_Other
-        } currentToken = Field_Type;
-
-        // the flags and field values on the current line
-        MailcapLineData data;
-
-        bool cont = TRUE;
-        while ( cont )
-        {
-            switch ( *pc )
-            {
-                case wxT('\\'):
-                    // interpret the next character literally (notice that
-                    // backslash can be used for line continuation)
-                    if ( *++pc == wxT('\0') )
-                    {
-                        // fetch the next line if there is one
-                        if ( nLine == nLineCount - 1 )
-                        {
-                            // something is wrong, bail out
-                            cont = FALSE;
-
-                            wxLogDebug(wxT("Mailcap file %s, line %lu: "
-                                           "'\\' on the end of the last line "
-                                           "ignored."),
-                                       strFileName.c_str(),
-                                       (unsigned long)nLine + 1);
-                        }
-                        else
-                        {
-                            // pass to the beginning of the next line
-                            pc = file[++nLine].c_str();
-
-                            // skip pc++ at the end of the loop
-                            continue;
-                        }
-                    }
-                    else
-                    {
-                        // just a normal character
-                        curField += *pc;
-                    }
-                    break;
-
-                case wxT('\0'):
-                    cont = FALSE;   // end of line reached, exit the loop
-
-                    // fall through to still process this field
-
-                case wxT(';'):
-                    // trim whitespaces from both sides
-                    curField.Trim(TRUE).Trim(FALSE);
-
-                    switch ( currentToken )
-                    {
-                        case Field_Type:
-                            data.type = curField.Lower();
-                            if ( data.type.empty() )
-                            {
-                                // I don't think that this is a valid mailcap
-                                // entry, but try to interpret it somehow
-                                data.type = _T('*');
-                            }
-
-                            if ( data.type.Find(wxT('/')) == wxNOT_FOUND )
-                            {
-                                // we interpret "type" as "type/*"
-                                data.type += wxT("/*");
-                            }
-
-                            currentToken = Field_OpenCmd;
-                            break;
-
-                        case Field_OpenCmd:
-                            data.cmdOpen = curField;
-
-                            currentToken = Field_Other;
-                            break;
-
-                        case Field_Other:
-                            if ( !ProcessOtherMailcapField(data, curField) )
-                            {
-                                // don't flood the user with error messages if
-                                // we don't understand something in his
-                                // mailcap, but give them in debug mode because
-                                // this might be useful for the programmer
-                                wxLogDebug
-                                (
-                                    wxT("Mailcap file %s, line %lu: "
-                                        "unknown field '%s' for the "
-                                        "MIME type '%s' ignored."),
-                                    strFileName.c_str(),
-                                    (unsigned long)nLine + 1,
-                                    curField.c_str(),
-                                    data.type.c_str()
-                                );
-                            }
-                            else if ( data.testfailed )
-                            {
-                                // skip this entry entirely
-                                cont = FALSE;
-                            }
-
-                            // it already has this value
-                            //currentToken = Field_Other;
-                            break;
-
-                        default:
-                            wxFAIL_MSG(wxT("unknown field type in mailcap"));
-                    }
-
-                    // next token starts immediately after ';'
-                    curField.Empty();
-                    break;
-
-                default:
-                    curField += *pc;
-            }
-
-            // continue in the same line
-            pc++;
-        }
-
-        // we read the entire entry, check what have we got
-        // ------------------------------------------------
-
-        // check that we really read something reasonable
-        if ( currentToken < Field_Other )
-        {
-            wxLogWarning(_("Mailcap file %s, line %d: incomplete entry "
-                           "ignored."),
-                         strFileName.c_str(), nLine + 1);
-
-            continue;
-        }
-
-        // if the test command failed, it's as if the entry were not there at
-        // all
-        if ( data.testfailed )
-        {
-            continue;
-        }
-
-        // support for flags:
-        //  1. create an xterm for 'needsterminal'
-        //  2. append "| $PAGER" for 'copiousoutput'
-        //
-        // Note that the RFC says that having both needsterminal and
-        // copiousoutput is probably a mistake, so it seems that running
-        // programs with copiousoutput inside an xterm as it is done now
-        // is a bad idea (FIXME)
-        if ( data.copiousoutput )
-        {
-            const wxChar *p = wxGetenv(_T("PAGER"));
-            data.cmdOpen << _T(" | ") << (p ? p : _T("more"));
-        }
-
-        if ( data.needsterminal )
-        {
-            data.cmdOpen = wxString::Format(_T("xterm -e sh -c '%s'"),
-                                            data.cmdOpen.c_str());
-        }
-
-        if ( !data.cmdOpen.empty() )
-        {
-            data.verbs.Insert(_T("open"), 0);
-            data.commands.Insert(data.cmdOpen, 0);
-        }
-
-        // we have to decide whether the new entry should replace any entries
-        // for the same MIME type we had previously found or not
-        bool overwrite;
-
-        // the fall back entries have the lowest priority, by definition
-        if ( fallback )
-        {
-            overwrite = FALSE;
-        }
-        else
-        {
-            // have we seen this one before?
-            int nIndex = m_aTypes.Index(data.type);
-
-            // and if we have, was it in this file?
-            overwrite = nIndex == wxNOT_FOUND ||
-                            aIndicesSeenHere.Index(nIndex) != wxNOT_FOUND;
-        }
-
-        wxLogTrace(TRACE_MIME, _T("mailcap %s: %s [%s]"),
-                   data.type.c_str(), data.cmdOpen.c_str(),
-                   overwrite ? _T("replace") : _T("add"));
-
-        int n = AddToMimeData
-                (
-                    data.type,
-                    data.icon,
-                    new wxMimeTypeCommands(data.verbs, data.commands),
-                    wxArrayString() /* extensions */,
-                    data.desc,
-                    overwrite
-                );
-
-        if ( overwrite )
-        {
-            aIndicesSeenHere.Add(n);
-        }
-    }
-
-    return TRUE;