static int
MimeInlineTextHTMLAsPlaintext_parse_eof (MimeObject *obj, PRBool abort_p)
{
  if (obj->closed_p)
    return 0;

  // This is a hack. We need to call parse_eof() of the super class to flush out any buffered data.
  // We can't call it yet for our direct super class, because it would "close" the output
  // (write tags such as </pre> and </div>). We'll do that after parsing the buffer.
  int status = ((MimeObjectClass*)&MIME_SUPERCLASS)->superclass->parse_eof(obj, abort_p);
  if (status < 0)
    return status;

  MimeInlineTextHTMLAsPlaintext *textHTMLPlain =
                                       (MimeInlineTextHTMLAsPlaintext *) obj;

  if (!textHTMLPlain || !textHTMLPlain->complete_buffer)
  {
    return 0;
  }
  nsString& cb = *(textHTMLPlain->complete_buffer);
  nsString asPlaintext;
  PRUint32 flags = nsIDocumentEncoder::OutputFormatted
    | nsIDocumentEncoder::OutputWrap
    | nsIDocumentEncoder::OutputFormatFlowed
    | nsIDocumentEncoder::OutputLFLineBreak
    | nsIDocumentEncoder::OutputNoScriptContent
    | nsIDocumentEncoder::OutputNoFramesContent
    | nsIDocumentEncoder::OutputBodyOnly;
  HTML2Plaintext(cb, asPlaintext, flags, 80);

  NS_ConvertUTF16toUTF8 resultCStr(asPlaintext);
  // TODO parse each line independently
  status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_line(
                             resultCStr.BeginWriting(),
                             resultCStr.Length(),
                             obj);

  cb.Truncate();

  if (status < 0)
    return status;

  // Second part of the flush hack. Pretend obj wasn't closed yet, so that our super class
  // gets a chance to write the closing.
  PRBool save_closed_p = obj->closed_p;
  obj->closed_p = PR_FALSE;
  status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
  // Restore closed_p.
  obj->closed_p = save_closed_p;
  return status;
}
static int
MimeInlineTextHTMLSanitized_parse_eof (MimeObject *obj, bool abort_p)
{
#ifdef DEBUG_BenB
printf("parse_eof\n");
#endif

  if (obj->closed_p)
    return 0;
  int status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(obj, abort_p);
  if (status < 0)
    return status;
  MimeInlineTextHTMLSanitized *textHTMLSan =
                                       (MimeInlineTextHTMLSanitized *) obj;

#ifdef DEBUG_BenB
printf(" cbp: %d\n", textHTMLSan->complete_buffer);
printf(" closed_p: %s\n", obj->closed_p?"true":"false");
#endif
  if (!textHTMLSan || !textHTMLSan->complete_buffer)
  {
#ifdef DEBUG_BenB
printf("/parse_eof (early exit)\n");
#endif
    return 0;
  }
#ifdef DEBUG_BenB
printf(" E1\n");
printf("buffer: -%s-\n", NS_LossyConvertUTF16toASCII(*textHTMLSan->complete_buffer).get());
#endif

#ifdef DEBUG_BenB
printf(" E2\n");
#endif
  nsString& cb = *(textHTMLSan->complete_buffer);
#ifdef DEBUG_BenB
printf(" E3\n");
#endif
  nsString sanitized;
#ifdef DEBUG_BenB
printf(" E4\n");
#endif
  HTMLSanitize(cb, sanitized);
#ifdef DEBUG_BenB
printf(" E5\n");
#endif

  NS_ConvertUTF16toUTF8 resultCStr(sanitized);
#ifdef DEBUG_BenB
printf(" E6\n");
#endif
  // TODO parse each line independently
  /* That function doesn't work correctly, if the first META tag is no
     charset spec. (It assumes that it's on its own line.)
     Most likely not fatally wrong, however. */
  status = ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_line(
                             resultCStr.BeginWriting(),
                             resultCStr.Length(),
                             obj);
#ifdef DEBUG_BenB
printf(" E7\n");
#endif

#ifdef DEBUG_BenB
printf(" E8\n");
#endif

  cb.Truncate();

#ifdef DEBUG_BenB
printf("/parse_eof\n");
#endif

  return status;
}