NS_IMETHODIMP nsMsgSaveAsListener::OnDataAvailable(nsIRequest* request, 
                                  nsISupports* aSupport,
                                  nsIInputStream* inStream, 
                                  uint64_t srcOffset,
                                  uint32_t count)
{
  nsresult rv;
  uint64_t available;
  rv = inStream->Available(&available);
  if (!m_writtenData)
  {
    m_writtenData = true;
    rv = SetupMsgWriteStream(m_outputFile, m_addDummyEnvelope);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  bool useCanonicalEnding = false;
  nsCOMPtr <nsIMsgMessageUrl> msgUrl = do_QueryInterface(aSupport);
  if (msgUrl)
    msgUrl->GetCanonicalLineEnding(&useCanonicalEnding);
  
  const char *lineEnding = (useCanonicalEnding) ? CRLF : MSG_LINEBREAK;
  uint32_t lineEndingLength = (useCanonicalEnding) ? 2 : MSG_LINEBREAK_LEN;
  
  uint32_t readCount, maxReadCount = SAVE_BUF_SIZE - m_leftOver;
  uint32_t writeCount;
  char *start, *end, lastCharInPrevBuf = '\0';
  uint32_t linebreak_len = 0;

  while (count > 0)
  {
      if (count < maxReadCount)
          maxReadCount = count;
      rv = inStream->Read(m_dataBuffer + m_leftOver,
                          maxReadCount,
                          &readCount);
      if (NS_FAILED(rv)) return rv;

      m_leftOver += readCount;
      m_dataBuffer[m_leftOver] = '\0';

      start = m_dataBuffer;
      // make sure we don't insert another LF, accidentally, by ignoring
      // second half of CRLF spanning blocks.
      if (lastCharInPrevBuf == '\r' && *start == '\n')
        start++;

      end = PL_strchr(start, '\r');
      if (!end)
          end = PL_strchr(start, '\n');
      else if (*(end+1) == '\n' && linebreak_len == 0)
          linebreak_len = 2;

      if (linebreak_len == 0) // not initialize yet
          linebreak_len = 1;

      count -= readCount;
      maxReadCount = SAVE_BUF_SIZE - m_leftOver;

      if (!end && count > maxReadCount)
          // must be a very very long line; sorry cannot handle it
          return NS_ERROR_FAILURE;

      while (start && end)
      {
          if (m_outputStream &&
              PL_strncasecmp(start, "X-Mozilla-Status:", 17) &&
              PL_strncasecmp(start, "X-Mozilla-Status2:", 18) &&
              PL_strncmp(start, "From - ", 7))
          {
              rv = m_outputStream->Write(start, end-start, &writeCount);
              nsresult tmp = m_outputStream->Write(lineEnding, lineEndingLength, &writeCount);
              if (NS_FAILED(tmp)) {
                rv = tmp;
              }
          }
          start = end+linebreak_len;
          if (start >= m_dataBuffer + m_leftOver)
          {
              maxReadCount = SAVE_BUF_SIZE;
              m_leftOver = 0;
              break;
          }
          end = PL_strchr(start, '\r');
          if (!end)
              end = PL_strchr(start, '\n');
          if (start && !end)
          {
              m_leftOver -= (start - m_dataBuffer);
              memcpy(m_dataBuffer, start,
                            m_leftOver+1); // including null
              maxReadCount = SAVE_BUF_SIZE - m_leftOver;
          }
      }
      if (NS_FAILED(rv)) return rv;
      if (end)
          lastCharInPrevBuf = *end;
  }
  return rv;
  
  //  rv = m_outputStream->WriteFrom(inStream, std::min(available, count), &bytesWritten);
}
NS_IMETHODIMP nsMsgSaveAsListener::OnDataAvailable(nsIRequest* request, 
                                  nsISupports* aSupport,
                                  nsIInputStream* inStream, 
                                  PRUint32 srcOffset,
                                  PRUint32 count)
{
  nsresult rv;
  PRUint32 available;
  rv = inStream->Available(&available);
  if (!m_writtenData)
  {
    m_writtenData = PR_TRUE;
    rv = SetupMsgWriteStream(m_outputFile, m_addDummyEnvelope);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  PRBool useCanonicalEnding = PR_FALSE;
  nsCOMPtr <nsIMsgMessageUrl> msgUrl = do_QueryInterface(aSupport);
  if (msgUrl)
    msgUrl->GetCanonicalLineEnding(&useCanonicalEnding);
  
  const char *lineEnding = (useCanonicalEnding) ? CRLF : MSG_LINEBREAK;
  PRUint32 lineEndingLength = (useCanonicalEnding) ? 2 : MSG_LINEBREAK_LEN;
  
  PRUint32 readCount, maxReadCount = SAVE_BUF_SIZE - m_leftOver;
  PRUint32 writeCount;
  char *start, *end;
  PRUint32 linebreak_len = 0;

  while (count > 0)
  {
      if (count < maxReadCount)
          maxReadCount = count;
      rv = inStream->Read(m_dataBuffer + m_leftOver,
                          maxReadCount,
                          &readCount);
      if (NS_FAILED(rv)) return rv;

      m_leftOver += readCount;
      m_dataBuffer[m_leftOver] = '\0';

      start = m_dataBuffer;
      end = PL_strchr(start, '\r');
      if (!end)
          end = PL_strchr(start, '\n');
      else if (*(end+1) == '\n' && linebreak_len == 0)
          linebreak_len = 2;

      if (linebreak_len == 0) // not initialize yet
          linebreak_len = 1;

      count -= readCount;
      maxReadCount = SAVE_BUF_SIZE - m_leftOver;

      if (!end && count > maxReadCount)
          // must be a very very long line; sorry cannot handle it
          return NS_ERROR_FAILURE;

      while (start && end)
      {
          if (PL_strncasecmp(start, "X-Mozilla-Status:", 17) &&
              PL_strncasecmp(start, "X-Mozilla-Status2:", 18) &&
              PL_strncmp(start, "From - ", 7))
          {
              rv = m_outputStream->Write(start, end-start, &writeCount);
              rv = m_outputStream->Write(lineEnding, lineEndingLength, &writeCount);
          }
          start = end+linebreak_len;
          if (start >= m_dataBuffer + m_leftOver)
          {
              maxReadCount = SAVE_BUF_SIZE;
              m_leftOver = 0;
              break;
          }
          end = PL_strchr(start, '\r');
          if (!end)
              end = PL_strchr(start, '\n');
          if (start && !end)
          {
              m_leftOver -= (start - m_dataBuffer);
              memcpy(m_dataBuffer, start,
                            m_leftOver+1); // including null
              maxReadCount = SAVE_BUF_SIZE - m_leftOver;
          }
      }
      if (NS_FAILED(rv)) return rv;
  }
  return rv;
  
  //  rv = m_outputStream->WriteFrom(inStream, PR_MIN(available, count), &bytesWritten);
}