if (NS_FAILED(rv)) { NS_IF_RELEASE(aListener); Alert("saveMessageFailed"); }
if (messageService) ReleaseMessageServiceFromURI(url, messageService);
nsMessenger::SaveAs(const char* url, PRBool asFile, nsIMsgIdentity* identity, nsIMsgWindow *aMsgWindow){    nsresult rv = NS_ERROR_FAILURE;    nsCOMPtr<nsIMsgMessageService> messageService;    nsCOMPtr<nsIUrlListener> urlListener;    nsSaveMsgListener *aListener = nsnull;    nsCOMPtr<nsIURI> aURL;    nsAutoString urlString;    char *urlCString = nsnull;    nsCOMPtr<nsISupports> channelSupport;    nsCOMPtr<nsIStreamListener> convertedListener;    PRBool needDummyHeader = PR_TRUE;    PRBool canonicalLineEnding = PR_FALSE;    PRInt16 saveAsFileType = 0; // 0 - raw, 1 = html, 2 = text;        nsCOMPtr<nsIStreamConverterService> streamConverterService = do_GetService(kIStreamConverterServiceCID, &rv);    if (NS_FAILED(rv)) goto done;        if (!url) {        rv = NS_ERROR_NULL_POINTER;        goto done;    }    rv = GetMessageServiceFromURI(url, getter_AddRefs(messageService));    if (NS_FAILED(rv)) goto done;    if (asFile) {        nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1", &rv);        if (NS_FAILED(rv)) goto done;        filePicker->Init(nsnull, GetString(NS_LITERAL_STRING("SaveMailAs").get()), nsIFilePicker::modeSave);        filePicker->SetDefaultString(GetString(NS_LITERAL_STRING("defaultSaveMessageAsFileName").get()));        filePicker->AppendFilter(GetString(NS_LITERAL_STRING("EMLFiles").get()),                                 NS_LITERAL_STRING("*.eml").get());        filePicker->AppendFilters(nsIFilePicker::filterHTML | nsIFilePicker::filterText | nsIFilePicker::filterAll);        PRInt16 dialogResult;        filePicker->Show(&dialogResult);        if (dialogResult == nsIFilePicker::returnCancel)            goto done;                    nsCOMPtr<nsILocalFile> localFile;        rv = filePicker->GetFile(getter_AddRefs(localFile));        if (NS_FAILED(rv)) goto done;                    nsXPIDLCString tmpFileName;        rv = localFile->GetLeafName(getter_Copies(tmpFileName));        if (NS_FAILED(rv)) goto done;        nsCAutoString fileName(tmpFileName);                    // First, check if they put ANY extension on the file, if not,        // then we should look at the type of file they have chosen and        // tack on the file extension for them.        //        if (fileName.RFind(".", PR_TRUE) != -1)        {            if (fileName.RFind(".htm", PR_TRUE) != -1)                saveAsFileType = 1;            else if (fileName.RFind(".txt", PR_TRUE) != -1)                saveAsFileType = 2;            else                saveAsFileType = 0;   // .eml type        } else {            saveAsFileType = 0; // .eml type        }        // XXX argh!  converting from nsILocalFile to nsFileSpec ... oh baby, lets drop from unicode to ascii too        //        nsXPIDLString path;        //        localFile->GetUnicodePath(getter_Copies(path));        nsXPIDLCString path;        localFile->GetPath(getter_Copies(path));        nsCOMPtr<nsIFileSpec> fileSpec = do_CreateInstance("@mozilla.org/filespec;1", &rv);        if (NS_FAILED(rv)) goto done;        fileSpec->SetNativePath(path);        aListener = new nsSaveMsgListener(fileSpec, this);        if (!aListener) {            rv = NS_ERROR_OUT_OF_MEMORY;            goto done;        }                NS_ADDREF(aListener);        rv = aListener->QueryInterface(NS_GET_IID(nsIUrlListener),                                       getter_AddRefs(urlListener));        if (NS_FAILED(rv)) goto done;                switch (saveAsFileType) {        case 0:        default:            rv = messageService->SaveMessageToDisk(url, fileSpec, PR_TRUE,                                                   urlListener, nsnull,                                                   PR_FALSE, mMsgWindow);            break;        case 1:        case 2:            urlString.AssignWithConversion(url);            // Setup the URL for a "Save As..." Operation...            // For now, if this is a save as TEXT operation, then do            // a "printing" operation            //            if (saveAsFileType == 1)                urlString.Append(NS_LITERAL_STRING("?header=saveas").get());            else                urlString.Append(NS_LITERAL_STRING("?header=print").get());                        urlCString = ToNewCString(urlString);            rv = CreateStartupUrl(urlCString, getter_AddRefs(aURL));            nsCRT::free(urlCString);            if (NS_FAILED(rv)) goto done;            aListener->m_channel = nsnull;            rv = NS_NewInputStreamChannel(getter_AddRefs(aListener->m_channel),                                          aURL,                                           nsnull,      // inputStream                                          nsnull,      // contentType                                          -1);         // contentLength            if (NS_FAILED(rv)) goto done;            aListener->m_outputFormat.AssignWithConversion(saveAsFileType == 1 ? TEXT_HTML : TEXT_PLAIN);                        // Mark the fact that we need to do charset handling/text conversion!            if (aListener->m_outputFormat.EqualsWithConversion(TEXT_PLAIN))                aListener->m_doCharsetConversion = PR_TRUE;                        channelSupport = do_QueryInterface(aListener->m_channel);                        rv = streamConverterService->AsyncConvertData(NS_ConvertASCIItoUCS2(MESSAGE_RFC822).get(),            // RICHIE - we should be able to go RFC822 to TXT, but not until            // Bug #1775 is fixed. aListener->m_outputFormat.get()                                                           NS_ConvertASCIItoUCS2(TEXT_HTML).get(),                                                           aListener,                                                          channelSupport,                                                          getter_AddRefs(convertedListener));            if (NS_FAILED(rv)) goto done;            rv = messageService->DisplayMessage(url, convertedListener,mMsgWindow,                                                nsnull, nsnull, nsnull);            break;        }    }    else    {        // ** save as Template        nsCOMPtr<nsIFileSpec> fileSpec;        nsFileSpec tmpFileSpec("nsmail.tmp");        rv = NS_NewFileSpecWithSpec(tmpFileSpec, getter_AddRefs(fileSpec));        if (NS_FAILED(rv)) goto done;        aListener = new nsSaveMsgListener(fileSpec, this);        if (!aListener) {            rv = NS_ERROR_OUT_OF_MEMORY;            goto done;        }                NS_ADDREF(aListener);        if (identity)            rv = identity->GetStationeryFolder(getter_Copies(aListener->m_templateUri));        if (NS_FAILED(rv)) goto done;        needDummyHeader =            PL_strcasestr(aListener->m_templateUri, "mailbox://")             != nsnull;        canonicalLineEnding =            PL_strcasestr(aListener->m_templateUri, "imap://")            != nsnull;        rv = aListener->QueryInterface(                                       NS_GET_IID(nsIUrlListener),                                       getter_AddRefs(urlListener));        if (NS_FAILED(rv)) goto done;        rv = messageService->SaveMessageToDisk(url, fileSpec,                                                needDummyHeader,                                               urlListener, nsnull,                                               canonicalLineEnding, mMsgWindow);     }done:    if (NS_FAILED(rv)) {        NS_IF_RELEASE(aListener);        Alert("saveMessageFailed");    }	return rv;}