nsresult nsEudoraCompose::ReadHeaders( ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy, SimpleBufferTonyRCopiedOnce& header)
{
  // This should be the headers...
  header.m_writeOffset = 0;

  nsresult rv;
  PRInt32 lineLen;
  PRInt32 endLen = -1;
  PRInt8 endBuffer = 0;

  while ((endLen = IsEndHeaders( copy)) == -1) {
    while ((lineLen = FindNextEndLine( copy)) == -1) {
      copy.m_writeOffset = copy.m_bytesInBuf;
      if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0( "*** ERROR, writing headers\n");
        return( NS_ERROR_FAILURE);
      }
      if (NS_FAILED( rv = FillMailBuffer( pState, copy))) {
        IMPORT_LOG0( "*** Error reading message headers\n");
        return( rv);
      }
      if (!copy.m_bytesInBuf) {
        IMPORT_LOG0( "*** Error, end of file while reading headers\n");
        return( NS_ERROR_FAILURE);
      }
    }
    copy.m_writeOffset += lineLen;
    if ((copy.m_writeOffset + 4) >= copy.m_bytesInBuf) {
      if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0( "*** ERROR, writing headers 2\n");
        return( NS_ERROR_FAILURE);
      }
      if (NS_FAILED( rv = FillMailBuffer( pState, copy))) {
        IMPORT_LOG0( "*** Error reading message headers 2\n");
        return( rv);
      }
    }
  }

  if (!header.Write( copy.m_pBuffer, copy.m_writeOffset)) {
    IMPORT_LOG0( "*** Error writing final headers\n");
    return( NS_ERROR_FAILURE);
  }
  if (!header.Write( (const char *)&endBuffer, 1)) {
    IMPORT_LOG0( "*** Error writing header trailing null\n");
    return( NS_ERROR_FAILURE);
  }

  copy.m_writeOffset += endLen;

  return( NS_OK);
}
nsresult nsEudoraMailbox::ReadNextMessage(ReadFileState *pState, SimpleBufferTonyRCopiedOnce& copy,
                                          SimpleBufferTonyRCopiedOnce& header, SimpleBufferTonyRCopiedOnce& body,
                                          nsCString& defaultDate, nsCString& bodyType, EudoraTOCEntry *pTocEntry)
{
  header.m_writeOffset = 0;
  body.m_writeOffset = 0;

  nsresult    rv;
  int32_t      lineLen;
  char      endBuffer = 0;

  lineLen = -1;
  // Find the from separator - we should actually be positioned at the
  // from separator, but for now, we'll verify this.
  while (lineLen == -1) {
    if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
      IMPORT_LOG0("*** Error, FillMailBuffer FAILED in ReadNextMessage\n");
      return rv;
    }
    lineLen = IsEudoraFromSeparator(copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, defaultDate);

    if (lineLen == -1) {
      while ((lineLen = FindStartLine(copy)) == -1) {
        copy.m_writeOffset = copy.m_bytesInBuf;
        if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
          IMPORT_LOG0("*** Error, FillMailBuffer FAILED in ReadNextMessage, looking for next start line\n");
          return rv;
        }
        if (!copy.m_bytesInBuf) {
          IMPORT_LOG0("*** Error, ReadNextMessage, looking for start of next line, got end of file.\n");
          return NS_ERROR_FAILURE;
        }
      }
      copy.m_writeOffset += lineLen;
      lineLen = -1;
    }
  }

  // Skip past the from line separator
  while ((lineLen = FindStartLine(copy)) == -1) {
    copy.m_writeOffset = copy.m_bytesInBuf;
    if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
      IMPORT_LOG0("*** Error, ReadNextMessage, FillMailBuffer failed looking for from sep\n");
      return rv;
    }
    if (!copy.m_bytesInBuf) {
      IMPORT_LOG0("*** Error, ReadNextMessage, end of file looking for from sep\n");
      return NS_ERROR_FAILURE;
    }
  }
  copy.m_writeOffset += lineLen;
  if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
    IMPORT_LOG0("*** Error, Unable to fill mail buffer after from sep.\n");
    return rv;
  }

  // This should be the headers...
  int32_t endLen = -1;
  while ((endLen = IsEndHeaders(copy)) == -1) {
    while ((lineLen = FindNextEndLine(copy)) == -1) {
      copy.m_writeOffset = copy.m_bytesInBuf;
      if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0("*** ERROR, writing headers\n");
        return NS_ERROR_FAILURE;
      }
      if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
        IMPORT_LOG0("*** Error reading message headers\n");
        return rv;
      }
      if (!copy.m_bytesInBuf) {
        IMPORT_LOG0("*** Error, end of file while reading headers\n");
        return NS_ERROR_FAILURE;
      }
    }
    copy.m_writeOffset += lineLen;
    if ((copy.m_writeOffset + 4) >= copy.m_bytesInBuf) {
      if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0("*** ERROR, writing headers 2\n");
        return NS_ERROR_FAILURE;
      }
      if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
        IMPORT_LOG0("*** Error reading message headers 2\n");
        return rv;
      }
    }
  }

  if (!header.Write(copy.m_pBuffer, copy.m_writeOffset)) {
    IMPORT_LOG0("*** Error writing final headers\n");
    return NS_ERROR_FAILURE;
  }

  if (pTocEntry) {
    // This is not the prettiest spot to stick this code, but it works and it was convenient.
    char    header_str[128];

    // Write X-Mozilla-Status header
    PR_snprintf(header_str, 128, MSG_LINEBREAK X_MOZILLA_STATUS_FORMAT MSG_LINEBREAK, pTocEntry->GetMozillaStatusFlags());
    header.Write(header_str, strlen(header_str));

    // Write X-Mozilla-Status2 header
    PR_snprintf(header_str, 128, X_MOZILLA_STATUS2_FORMAT MSG_LINEBREAK, pTocEntry->GetMozillaStatus2Flags());
    header.Write(header_str, strlen(header_str));

    // Format and write X-Mozilla-Keys header
    nsCString  keywordHdr(X_MOZILLA_KEYWORDS);
    if (pTocEntry->HasEudoraLabel()) {
      PR_snprintf(header_str, 128, "eudoralabel%d", pTocEntry->GetLabelNumber());
      keywordHdr.Replace(sizeof(HEADER_X_MOZILLA_KEYWORDS) + 1, strlen(header_str), header_str);
    }
    header.Write(keywordHdr.get(), keywordHdr.Length());
  }

  if (!header.Write(&endBuffer, 1)) {
    IMPORT_LOG0("*** Error writing header trailing null\n");
    return NS_ERROR_FAILURE;
  }

  copy.m_writeOffset += endLen;
  if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
    IMPORT_LOG0("*** Error reading beginning of message body\n");
    return rv;
  }

  EmptyAttachments();

  // Get the body!
  // Read one line at a time here and look for the next separator
  nsCString tmp;
  bool insideEudoraTags = false;
  // by default we consider the body text to be plain text
  bodyType = "text/plain";

  while ((lineLen = IsEudoraFromSeparator(copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, tmp)) == -1) {
    int32_t tagLength = 0;
    if (IsEudoraTag (copy.m_pBuffer + copy.m_writeOffset, copy.m_bytesInBuf - copy.m_writeOffset, insideEudoraTags, bodyType, tagLength)) {
      // We don't want to keep eudora tags so skip over them.

      // let's write the previous text
      if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0("*** Error writing to message body\n");
        return NS_ERROR_FAILURE;
      }

      // we want to skip over the tag...for now we are assuming the tag is always at the start of line.
      copy.m_writeOffset += tagLength;
        if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
          IMPORT_LOG0("*** Error reading message body\n");
          return rv;
        }

      if (!copy.m_bytesInBuf)
        break;

      continue;
    }

    // Eudora Attachment lines are always outside Eudora Tags
    // so we shouldn't try to find one here
    if (!insideEudoraTags) {
    // Debatable is whether or not to exclude these lines from the
    // text of the message, I prefer not to in case the original
    // attachment is actually missing.
    rv = ExamineAttachment(copy);
    if (NS_FAILED(rv)) {
      IMPORT_LOG0("*** Error examining attachment line\n");
      return rv;
    }
    }

    while (((lineLen = FindStartLine(copy)) == -1) && copy.m_bytesInBuf) {
      copy.m_writeOffset = copy.m_bytesInBuf;
      if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0("*** Error writing to message body\n");
        return NS_ERROR_FAILURE;
      }
      if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
        IMPORT_LOG0("*** Error reading message body\n");
        return rv;
      }
    }
    if (!copy.m_bytesInBuf)
      break;

    copy.m_writeOffset += lineLen;

    // found the start of the next line
    // make sure it's long enough to check for the from line
    if ((copy.m_writeOffset + 2048) >= copy.m_bytesInBuf) {
      if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) {
        IMPORT_LOG0("*** Error writing to message body 2\n");
        return NS_ERROR_FAILURE;
      }
      if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
        IMPORT_LOG0("*** Error reading message body 2\n");
        return rv;
      }
    }
  }

  // the start of the current line is a from, we-re done
  if (!body.Write(copy.m_pBuffer, copy.m_writeOffset)) {
    IMPORT_LOG0("*** Error writing final message body\n");
    return NS_ERROR_FAILURE;
  }
  if (!body.Write(&endBuffer, 1)) {
    IMPORT_LOG0("*** Error writing body trailing null\n");
    IMPORT_LOG2("\tbody.m_size: %ld, body.m_writeOffset: %ld\n", body.m_size, body.m_writeOffset);
    return NS_ERROR_FAILURE;
  }
  if (NS_FAILED(rv = FillMailBuffer(pState, copy))) {
    IMPORT_LOG0("*** Error filling mail buffer for next read message\n");
    return rv;
  }

  return NS_OK;
}