NS_IMETHODIMP nsMailboxUrl::GetUri(char ** aURI)
{
  // if we have been given a uri to associate with this url, then use it
  // otherwise try to reconstruct a URI on the fly....

  if (!mURI.IsEmpty())
    *aURI = ToNewCString(mURI);
  else
  {
    if (m_filePath)
    {
      nsAutoCString baseUri;
      nsresult rv;
      nsCOMPtr<nsIMsgAccountManager> accountManager =
        do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
      NS_ENSURE_SUCCESS(rv, rv);

      // we blow off errors here so that we can open attachments
      // in .eml files.
      (void) accountManager->FolderUriForPath(m_filePath, baseUri);
      if (baseUri.IsEmpty())
        m_baseURL->GetSpec(baseUri);
      nsCString baseMessageURI;
      nsCreateLocalBaseMessageURI(baseUri, baseMessageURI);
      nsAutoCString uriStr;
      nsBuildLocalMessageURI(baseMessageURI.get(), m_messageKey, uriStr);
      *aURI = ToNewCString(uriStr);
    }
    else
      *aURI = nullptr;
  }

  return NS_OK;
}
NS_IMETHODIMP
nsPop3Sink::IncorporateComplete(nsIMsgWindow *aMsgWindow, int32_t aSize)
{
  if (m_buildMessageUri && !m_baseMessageUri.IsEmpty() && m_newMailParser &&
      m_newMailParser->m_newMsgHdr)
  {
    nsMsgKey msgKey;
    m_newMailParser->m_newMsgHdr->GetMessageKey(&msgKey);
    m_messageUri.Truncate();
    nsBuildLocalMessageURI(m_baseMessageUri.get(), msgKey, m_messageUri);
  }

  nsresult rv = WriteLineToMailbox(NS_LITERAL_CSTRING(MSG_LINEBREAK));
  NS_ENSURE_SUCCESS(rv, rv);
  bool leaveOnServer = false;
  m_popServer->GetLeaveMessagesOnServer(&leaveOnServer);
  // We need to flush the output stream, in case mail filters move
  // the new message, which relies on all the data being flushed.
  rv = m_outFileStream->Flush(); // Make sure the message is written to the disk
  NS_ENSURE_SUCCESS(rv, rv);
  NS_ASSERTION(m_newMailParser, "could not get m_newMailParser");
  if (m_newMailParser)
  {
    // PublishMsgHdr clears m_newMsgHdr, so we need a comptr to
    // hold onto it.
    nsCOMPtr<nsIMsgDBHdr> hdr = m_newMailParser->m_newMsgHdr;
    NS_ASSERTION(hdr, "m_newMailParser->m_newMsgHdr wasn't set");
    if (!hdr)
      return NS_ERROR_FAILURE;

    nsCOMPtr<nsIMsgLocalMailFolder> localFolder = do_QueryInterface(m_folder);
    bool doSelect = false;

    // aSize is only set for partial messages. For full messages,
    // check to see if we're replacing an old partial message.
    if (!aSize && localFolder)
      (void) localFolder->DeleteDownloadMsg(hdr, &doSelect);

    // If a header already exists for this message (for example, when
    // getting a complete message when a partial exists), then update the new
    // header from the old.
    if (!m_origMessageUri.IsEmpty() && localFolder)
    {
      nsCOMPtr <nsIMsgDBHdr> oldMsgHdr;
      rv = GetMsgDBHdrFromURI(m_origMessageUri.get(), getter_AddRefs(oldMsgHdr));
      if (NS_SUCCEEDED(rv) && oldMsgHdr)
        localFolder->UpdateNewMsgHdr(oldMsgHdr, hdr);
    }

    if (m_downloadingToTempFile)
    {
      // close file to give virus checkers a chance to do their thing...
      m_outFileStream->Flush();
      m_outFileStream->Close();
      m_newMailParser->FinishHeader();
      // need to re-open the inbox file stream.
      bool exists;
      m_tmpDownloadFile->Exists(&exists);
      if (!exists)
        return HandleTempDownloadFailed(aMsgWindow);

      nsCOMPtr <nsIInputStream> inboxInputStream = do_QueryInterface(m_outFileStream);
      rv = MsgReopenFileStream(m_tmpDownloadFile, inboxInputStream);
      NS_ENSURE_SUCCESS(rv, HandleTempDownloadFailed(aMsgWindow));
      if (m_outFileStream)
      {
        int64_t tmpDownloadFileSize;
        uint32_t msgSize;
        hdr->GetMessageSize(&msgSize);
        // we need to clone because nsLocalFileUnix caches its stat result,
        // so it doesn't realize the file has changed size.
        nsCOMPtr <nsIFile> tmpClone;
        rv = m_tmpDownloadFile->Clone(getter_AddRefs(tmpClone));
        NS_ENSURE_SUCCESS(rv, rv);
        tmpClone->GetFileSize(&tmpDownloadFileSize);

        if (msgSize > tmpDownloadFileSize)
          rv = NS_MSG_ERROR_WRITING_MAIL_FOLDER;
        else
          rv = m_newMailParser->AppendMsgFromStream(inboxInputStream, hdr,
                                                    msgSize, m_folder);
        if (NS_FAILED(rv))
          return HandleTempDownloadFailed(aMsgWindow);

        m_outFileStream->Close(); // close so we can truncate.
        m_tmpDownloadFile->SetFileSize(0);
      }
      else
      {
          return HandleTempDownloadFailed(aMsgWindow);
        // need to give an error here.
      }
    }
    else
    {
      m_msgStore->FinishNewMessage(m_outFileStream, hdr);
    }
    m_newMailParser->PublishMsgHeader(aMsgWindow);
    // run any reply/forward filter after we've finished with the
    // temp quarantine file, and/or moved the message to another folder.
    m_newMailParser->ApplyForwardAndReplyFilter(aMsgWindow);
    if (aSize)
      hdr->SetUint32Property("onlineSize", aSize);

    // if DeleteDownloadMsg requested it, select the new message
    else if (doSelect)
      (void) localFolder->SelectDownloadMsg();
  }

#ifdef DEBUG
  printf("Incorporate message complete.\n");
#endif
  nsCOMPtr<nsIPop3Service> pop3Service(do_GetService(NS_POP3SERVICE_CONTRACTID1, &rv));
  NS_ENSURE_SUCCESS(rv, rv);
  pop3Service->NotifyDownloadProgress(m_folder, ++m_numMsgsDownloaded, m_numNewMessages);
  return NS_OK;
}