Index: src/test/java/org/apache/james/mime4j/io/RootInputStreamTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/io/RootInputStreamTest.java	(revision 738600)
+++ src/test/java/org/apache/james/mime4j/io/RootInputStreamTest.java	(working copy)
@@ -1,98 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you under the Apache License, Version 2.0 (the            *
- * "License"); you may not use this file except in compliance   *
- * with the License.  You may obtain a copy of the License at   *
- *                                                              *
- *   http://www.apache.org/licenses/LICENSE-2.0                 *
- *                                                              *
- * Unless required by applicable law or agreed to in writing,   *
- * software distributed under the License is distributed on an  *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
- * KIND, either express or implied.  See the License for the    *
- * specific language governing permissions and limitations      *
- * under the License.                                           *
- ****************************************************************/
-
-package org.apache.james.mime4j.io;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-import org.apache.james.mime4j.io.RootInputStream;
-
-
-import junit.framework.TestCase;
-
-public class RootInputStreamTest extends TestCase {
-
-    public void testTruncate() throws IOException {
-        String s = "Yada yada yada";
-        RootInputStream is = 
-            new RootInputStream(new ByteArrayInputStream(s.getBytes()));
-        assertEquals(s.charAt(0), (char) is.read());
-        assertEquals(s.charAt(1), (char) is.read());
-        assertEquals(s.charAt(2), (char) is.read());
-        assertEquals(s.charAt(3), (char) is.read());
-        is.truncate();
-        assertEquals(-1, is.read());
-        byte[] buf = new byte[100];
-        assertEquals(-1, is.read(buf));
-        assertEquals(-1, is.read(buf, 2, 5));
-    }
-
-    /**
-     * Tests that reading single bytes updates the line number appropriately.
-     */
-    public void testReadSingleByte() throws IOException {
-        String s = "Yada\r\nyada\r\nyada\r\n";
-        RootInputStream is = 
-            new RootInputStream(new ByteArrayInputStream(s.getBytes()));
-        
-        for (int i = 0; i < 6; i++) {
-            assertEquals(1, is.getLineNumber());
-            is.read();
-        }
-        
-        for (int i = 6; i < 12; i++) {
-            assertEquals(2, is.getLineNumber());
-            is.read();
-        }
-        
-        for (int i = 12; i < 18; i++) {
-            assertEquals(3, is.getLineNumber());
-            is.read();
-        }
-        
-        assertEquals(4, is.getLineNumber());
-        assertEquals(-1, is.read());
-    }
-    
-    /**
-     * Tests that reading multiple bytes at once 
-     * updates the line number appropriately.
-     */
-    public void testReadManyBytes() throws IOException {
-        String s = "Yada\r\nyada\r\nyada\r\n";
-        RootInputStream is = 
-            new RootInputStream(new ByteArrayInputStream(s.getBytes()));
-        
-        byte[] buf = new byte[4];
-        assertEquals(1, is.getLineNumber());
-        is.read(buf);
-        assertEquals(1, is.getLineNumber());
-        is.read(buf);
-        assertEquals(2, is.getLineNumber());
-        is.read(buf);
-        assertEquals(3, is.getLineNumber());
-        is.read(buf);
-        assertEquals(3, is.getLineNumber());
-        is.read(buf);
-        assertEquals(4, is.getLineNumber());
-        
-        assertEquals(-1, is.read());
-    }
-}
Index: src/test/java/org/apache/james/mime4j/io/LineNumberInputStreamTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/io/LineNumberInputStreamTest.java	(revision 0)
+++ src/test/java/org/apache/james/mime4j/io/LineNumberInputStreamTest.java	(revision 0)
@@ -0,0 +1,81 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mime4j.io;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.james.mime4j.io.LineNumberInputStream;
+
+import junit.framework.TestCase;
+
+public class LineNumberInputStreamTest extends TestCase {
+    /**
+     * Tests that reading single bytes updates the line number appropriately.
+     */
+    public void testReadSingleByte() throws IOException {
+        String s = "Yada\r\nyada\r\nyada\r\n";
+        LineNumberInputStream is = new LineNumberInputStream(
+                new ByteArrayInputStream(s.getBytes()));
+
+        for (int i = 0; i < 6; i++) {
+            assertEquals(1, is.getLineNumber());
+            is.read();
+        }
+
+        for (int i = 6; i < 12; i++) {
+            assertEquals(2, is.getLineNumber());
+            is.read();
+        }
+
+        for (int i = 12; i < 18; i++) {
+            assertEquals(3, is.getLineNumber());
+            is.read();
+        }
+
+        assertEquals(4, is.getLineNumber());
+        assertEquals(-1, is.read());
+    }
+
+    /**
+     * Tests that reading multiple bytes at once updates the line number
+     * appropriately.
+     */
+    public void testReadManyBytes() throws IOException {
+        String s = "Yada\r\nyada\r\nyada\r\n";
+        LineNumberInputStream is = new LineNumberInputStream(
+                new ByteArrayInputStream(s.getBytes()));
+
+        byte[] buf = new byte[4];
+        assertEquals(1, is.getLineNumber());
+        is.read(buf);
+        assertEquals(1, is.getLineNumber());
+        is.read(buf);
+        assertEquals(2, is.getLineNumber());
+        is.read(buf);
+        assertEquals(3, is.getLineNumber());
+        is.read(buf);
+        assertEquals(3, is.getLineNumber());
+        is.read(buf);
+        assertEquals(4, is.getLineNumber());
+
+        assertEquals(-1, is.read());
+    }
+}
Index: src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java	(revision 738600)
+++ src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java	(working copy)
@@ -26,7 +26,7 @@
 import org.apache.james.mime4j.io.BufferedLineReaderInputStream;
 import org.apache.james.mime4j.io.MaxHeaderLimitException;
 import org.apache.james.mime4j.io.MaxLineLimitException;
-import org.apache.james.mime4j.io.RootInputStream;
+import org.apache.james.mime4j.io.LineNumberInputStream;
 import org.apache.james.mime4j.parser.EntityStateMachine;
 import org.apache.james.mime4j.parser.EntityStates;
 import org.apache.james.mime4j.parser.MimeEntity;
@@ -47,11 +47,11 @@
             "a very important message";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 12); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 12); 
         
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -134,11 +134,11 @@
             "Goodbye!";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 24); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 24); 
         
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -247,11 +247,11 @@
             "Goodbye!";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 24); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 24); 
         
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -344,13 +344,13 @@
             "a very important message";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 12); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 12); 
         
         MimeEntityConfig config = new MimeEntityConfig();
         config.setMaxLineLen(50);
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -398,13 +398,13 @@
             "a very important message";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 12); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 12); 
         
         MimeEntityConfig config = new MimeEntityConfig();
         config.setMaxLineLen(50);
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -456,13 +456,13 @@
             "a very important message";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 12); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 12); 
         
         MimeEntityConfig config = new MimeEntityConfig();
         config.setMaxHeaderCount(20);
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
@@ -504,13 +504,13 @@
             "DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS DoS\r\n";
         byte[] raw = message.getBytes("US-ASCII");
         ByteArrayInputStream instream = new ByteArrayInputStream(raw);
-        RootInputStream rootStream = new RootInputStream(instream); 
-        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(rootStream, 12); 
+        LineNumberInputStream lineInput = new LineNumberInputStream(instream); 
+        BufferedLineReaderInputStream rawstream = new BufferedLineReaderInputStream(lineInput, 12); 
         
         MimeEntityConfig config = new MimeEntityConfig();
         config.setMaxContentLen(100);
         MimeEntity entity = new MimeEntity(
-                rootStream,
+                lineInput,
                 rawstream,
                 null,
                 EntityStates.T_START_MESSAGE,
Index: src/main/java/org/apache/james/mime4j/io/RootInputStream.java
===================================================================
--- src/main/java/org/apache/james/mime4j/io/RootInputStream.java	(revision 738600)
+++ src/main/java/org/apache/james/mime4j/io/RootInputStream.java	(working copy)
@@ -1,100 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you under the Apache License, Version 2.0 (the            *
- * "License"); you may not use this file except in compliance   *
- * with the License.  You may obtain a copy of the License at   *
- *                                                              *
- *   http://www.apache.org/licenses/LICENSE-2.0                 *
- *                                                              *
- * Unless required by applicable law or agreed to in writing,   *
- * software distributed under the License is distributed on an  *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
- * KIND, either express or implied.  See the License for the    *
- * specific language governing permissions and limitations      *
- * under the License.                                           *
- ****************************************************************/
-
-package org.apache.james.mime4j.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * <code>InputStream</code> used by the parser to wrap the original user
- * supplied stream. This stream keeps track of the current line number and
- * can also be truncated. When truncated the stream will appear to have
- * reached end of file. This is used by the parser's 
- * {@link org.apache.james.mime4j.parser.MimeStreamParser#stop()} method.
- */
-public class RootInputStream extends FilterInputStream {
-    private int lineNumber = 1;
-    private boolean truncated = false;
-
-    /**
-     * Creates a new <code>RootInputStream</code>.
-     * 
-     * @param is the stream to read from.
-     */
-    public RootInputStream(InputStream is) {
-        super(is);
-    }
-
-    /**
-     * Gets the current line number starting at 1 
-     * (the number of <code>\r\n</code> read so far plus 1).
-     * 
-     * @return the current line number.
-     */
-    public int getLineNumber() {
-        return lineNumber;
-    }
-    
-    /**
-     * Truncates this <code>InputStream</code>. After this call any 
-     * call to {@link #read()}, {@link #read(byte[])} or 
-     * {@link #read(byte[], int, int)} will return
-     * -1 as if end-of-file had been reached.
-     */
-    public void truncate() {
-        this.truncated = true;
-    }
-    
-    /**
-     * @see java.io.InputStream#read()
-     */
-    @Override
-    public int read() throws IOException {
-        if (truncated) {
-            return -1;
-        }
-        
-        int b = in.read();
-        if (b == '\n') {
-            lineNumber++;
-        }
-        return b;
-    }
-    
-    /**
-     * 
-     * @see java.io.InputStream#read(byte[], int, int)
-     */
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        if (truncated) {
-            return -1;
-        }
-        
-        int n = in.read(b, off, len);
-        for (int i = off; i < off + n; i++) {
-            if (b[i] == '\n') {
-                lineNumber++;
-            }
-        }
-        return n;
-    }
-}
Index: src/main/java/org/apache/james/mime4j/io/LineNumberSource.java
===================================================================
--- src/main/java/org/apache/james/mime4j/io/LineNumberSource.java	(revision 0)
+++ src/main/java/org/apache/james/mime4j/io/LineNumberSource.java	(revision 0)
@@ -0,0 +1,30 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mime4j.io;
+
+public interface LineNumberSource {
+    /**
+     * Gets the current line number starting at 1 (the number of
+     * <code>\r\n</code> read so far plus 1).
+     * 
+     * @return the current line number.
+     */
+    int getLineNumber();
+}
Index: src/main/java/org/apache/james/mime4j/io/LineNumberInputStream.java
===================================================================
--- src/main/java/org/apache/james/mime4j/io/LineNumberInputStream.java	(revision 0)
+++ src/main/java/org/apache/james/mime4j/io/LineNumberInputStream.java	(revision 0)
@@ -0,0 +1,67 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mime4j.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <code>InputStream</code> used by the parser to wrap the original user
+ * supplied stream. This stream keeps track of the current line number.
+ */
+public class LineNumberInputStream extends FilterInputStream implements
+        LineNumberSource {
+    private int lineNumber = 1;
+
+    /**
+     * Creates a new <code>LineNumberInputStream</code>.
+     * 
+     * @param is
+     *            the stream to read from.
+     */
+    public LineNumberInputStream(InputStream is) {
+        super(is);
+    }
+
+    public int getLineNumber() {
+        return lineNumber;
+    }
+
+    @Override
+    public int read() throws IOException {
+        int b = in.read();
+        if (b == '\n') {
+            lineNumber++;
+        }
+        return b;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        int n = in.read(b, off, len);
+        for (int i = off; i < off + n; i++) {
+            if (b[i] == '\n') {
+                lineNumber++;
+            }
+        }
+        return n;
+    }
+}
Index: src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java	(revision 738600)
+++ src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java	(working copy)
@@ -117,6 +117,10 @@
         return result;
     }
 
+    /**
+     * Returns the current line number or <code>-1</code> if line number
+     * information is not available.
+     */
     protected abstract int getLineNumber();
     
     protected abstract LineReaderInputStream getDataStream();
@@ -308,15 +312,18 @@
      * or for logging
      */
     protected String message(Event event) {
-        String preamble = "Line " + getLineNumber() + ": ";
         final String message;
         if (event == null) {
             message = "Event is unexpectedly null.";
         } else {
             message = event.toString();
         }
-        final String result = preamble + message;
-        return result;
+
+        int lineNumber = getLineNumber();
+        if (lineNumber <= 0)
+            return message;
+        else
+            return "Line " + lineNumber + ": " + message;
     }
     
     /**
Index: src/main/java/org/apache/james/mime4j/parser/MimeEntity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/MimeEntity.java	(revision 738600)
+++ src/main/java/org/apache/james/mime4j/parser/MimeEntity.java	(working copy)
@@ -28,10 +28,10 @@
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
 import org.apache.james.mime4j.io.BufferedLineReaderInputStream;
 import org.apache.james.mime4j.io.LimitedInputStream;
+import org.apache.james.mime4j.io.LineNumberSource;
 import org.apache.james.mime4j.io.LineReaderInputStream;
 import org.apache.james.mime4j.io.LineReaderInputStreamAdaptor;
 import org.apache.james.mime4j.io.MimeBoundaryInputStream;
-import org.apache.james.mime4j.io.RootInputStream;
 import org.apache.james.mime4j.util.MimeUtil;
 
 public class MimeEntity extends AbstractEntity {
@@ -45,7 +45,7 @@
      */
     private static final int T_IN_MESSAGE = -3;
 
-    private final RootInputStream rootStream;
+    private final LineNumberSource lineSource;
     private final BufferedLineReaderInputStream inbuffer;
     
     private int recursionMode;
@@ -56,14 +56,14 @@
     private byte[] tmpbuf;
     
     public MimeEntity(
-            RootInputStream rootStream,
+            LineNumberSource lineSource,
             BufferedLineReaderInputStream inbuffer,
             BodyDescriptor parent, 
             int startState, 
             int endState,
             MimeEntityConfig config) {
         super(parent, startState, endState, config);
-        this.rootStream = rootStream;
+        this.lineSource = lineSource;
         this.inbuffer = inbuffer;
         this.dataStream = new LineReaderInputStreamAdaptor(
                 inbuffer,
@@ -72,12 +72,12 @@
     }
 
     public MimeEntity(
-            RootInputStream rootStream,
+            LineNumberSource lineSource,
             BufferedLineReaderInputStream inbuffer,
             BodyDescriptor parent, 
             int startState, 
             int endState) {
-        this(rootStream, inbuffer, parent, startState, endState, 
+        this(lineSource, inbuffer, parent, startState, endState, 
                 new MimeEntityConfig());
     }
 
@@ -99,7 +99,10 @@
     
     @Override
     protected int getLineNumber() {
-        return rootStream.getLineNumber();
+        if (lineSource == null)
+            return -1;
+        else
+            return lineSource.getLineNumber();
     }
     
     @Override
@@ -255,7 +258,7 @@
             return message;
         } else {
             MimeEntity message = new MimeEntity(
-                    rootStream, 
+                    lineSource, 
                     new BufferedLineReaderInputStream(
                             instream, 
                             4 * 1024,
@@ -279,7 +282,7 @@
                     4 * 1024,
                     config.getMaxLineLen());
             MimeEntity mimeentity = new MimeEntity(
-                    rootStream, 
+                    lineSource, 
                     stream,
                     body, 
                     EntityStates.T_START_BODYPART, 
Index: src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java	(revision 738600)
+++ src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java	(working copy)
@@ -33,7 +33,8 @@
 import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
 import org.apache.james.mime4j.io.BufferedLineReaderInputStream;
-import org.apache.james.mime4j.io.RootInputStream;
+import org.apache.james.mime4j.io.LineNumberInputStream;
+import org.apache.james.mime4j.io.LineNumberSource;
 import org.apache.james.mime4j.util.CharsetUtil;
 import org.apache.james.mime4j.util.MimeUtil;
 
@@ -108,7 +109,6 @@
     private EntityStateMachine currentStateMachine;
     private int recursionMode = M_RECURSE;
     private BufferedLineReaderInputStream inbuffer;
-    private RootInputStream rootInputStream;
     
     /**
      * Constructs a standard (lax) stream.
@@ -151,9 +151,16 @@
 
     private void doParse(InputStream stream, String contentType) {
         entities.clear();
-        rootInputStream = new RootInputStream(stream);
+
+        LineNumberSource lineSource = null;
+        if (config.isCountLineNumbers()) {
+            LineNumberInputStream lineInput = new LineNumberInputStream(stream);
+            lineSource = lineInput;
+            stream = lineInput;
+        }
+
         inbuffer = new BufferedLineReaderInputStream(
-                rootInputStream, 
+                stream, 
                 4 * 1024,
                 config.getMaxLineLen());
         switch (recursionMode) {
@@ -166,7 +173,7 @@
             // expected to be called only at start of paring
         case M_RECURSE:
             MimeEntity mimeentity = new MimeEntity(
-                    rootInputStream,
+                    lineSource,
                     inbuffer,
                     null, 
                     T_START_MESSAGE, 
@@ -237,7 +244,9 @@
      */
     public void stop() {
         inbuffer.clear();
-        rootInputStream.truncate();
+
+        // FIXME: move truncate functionality somewhere else
+        // lineInput.truncate();
     }
 
     /**
Index: src/main/java/org/apache/james/mime4j/parser/MimeEntityConfig.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/MimeEntityConfig.java	(revision 738600)
+++ src/main/java/org/apache/james/mime4j/parser/MimeEntityConfig.java	(working copy)
@@ -31,6 +31,7 @@
     private int maxLineLen;
     private int maxHeaderCount;
     private long maxContentLen;
+    private boolean countLineNumbers;
     
     public MimeEntityConfig() {
         this.maximalBodyDescriptor = false;
@@ -38,6 +39,7 @@
         this.maxLineLen = 1000;
         this.maxHeaderCount = 1000;
         this.maxContentLen = -1;
+        this.countLineNumbers = false;
     }
     
     public boolean isMaximalBodyDescriptor() {
@@ -137,6 +139,26 @@
         return maxContentLen;
     }
 
+    /**
+     * Defines whether the parser should count line numbers. If enabled line
+     * numbers are included in the debug output.
+     * 
+     * @param countLineNumbers
+     *            value of the line number counting mode.
+     */
+    public void setCountLineNumbers(boolean countLineNumbers) {
+        this.countLineNumbers = countLineNumbers;
+    }
+
+    /**
+     * Returns the value of the line number counting mode.
+     * 
+     * @return value of the line number counting mode.
+     */
+    public boolean isCountLineNumbers() {
+        return countLineNumbers;
+    }
+
     @Override
     public MimeEntityConfig clone() {
         try {
@@ -149,15 +171,11 @@
     
     @Override
     public String toString() {
-        StringBuilder buffer = new StringBuilder(128);
-        buffer.append("[max body descriptor: ");
-        buffer.append(Boolean.toString(this.maximalBodyDescriptor));
-        buffer.append("][strict parsing: ");
-        buffer.append(Boolean.toString(this.strictParsing));
-        buffer.append("][max header length: ");
-        buffer.append(Integer.toString(this.maxLineLen));
-        buffer.append("]");
-        return buffer.toString();
+        return "[max body descriptor: " + maximalBodyDescriptor
+                + ", strict parsing: " + strictParsing + ", max line length: "
+                + maxLineLen + ", max header count: " + maxHeaderCount
+                + ", max content length: " + maxContentLen
+                + ", count line numbers: " + countLineNumbers + "]";
     }
     
 }
