class MimeMessageWrapper extends MimeMessage implements Disposable {

    public synchronized InputStream getMessageInputStream() throws MessagingException {
        if (!messageParsed && !isModified() && source != null) {
            try {
                return source.getInputStream();
            } catch (IOException e) {
                throw new MessagingException("Unable to get inputstream", e);
            }
        } else {
            try {

                // Try to optimize if possible to prevent OOM on big mails.
                // See JAMES-1252 for an example
                if (!bodyModified && source != null) {
                    // ok only the headers were modified so we don't need to
                    // copy the whole message content into memory
                    InputStream in = source.getInputStream();
                    
                    // skip over headers from original stream we want to use the
                    // in memory ones
                    new MailHeaders(in);

                    // now construct the new stream using the in memory headers
                    // and the body from the original source
                    return new SequenceInputStream(new InternetHeadersInputStream(getAllHeaderLines()), in);
                } else {
                    // the body was changed so we have no other solution to copy
                    // it into memory first :(
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    writeTo(out);
                    return new ByteArrayInputStream(out.toByteArray());
                }
            } catch (IOException e) {
                throw new MessagingException("Unable to get inputstream", e);
            }
        }
    }

    private  MimeMessageWrapper(Session session);
    public  MimeMessageWrapper(Session session, MimeMessageSource source);
    public  MimeMessageWrapper(MimeMessageSource source);
    public  MimeMessageWrapper(MimeMessage original);

}