Index: src/test/java/org/apache/james/mime4j/field/ContentTypeFieldTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/ContentTypeFieldTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/ContentTypeFieldTest.java	(working copy)
@@ -20,7 +20,7 @@
 package org.apache.james.mime4j.field;
 
 import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.log4j.BasicConfigurator;
 
 import junit.framework.TestCase;
@@ -36,24 +36,24 @@
     public void testMimeTypeWithSemiColonNoParams() throws Exception  {
         ContentTypeField f = null;
         
-        f = (ContentTypeField) Field.parse("Content-Type: text/html;");
+        f = (ContentTypeField) AbstractField.parse("Content-Type: text/html;");
         assertEquals("text/html", f.getMimeType());
     }
     
     public void testGetMimeType() throws Exception {
         ContentTypeField f = null;
         
-        f = (ContentTypeField) Field.parse("Content-Type: text/PLAIN");
+        f = (ContentTypeField) AbstractField.parse("Content-Type: text/PLAIN");
         assertEquals("text/plain", f.getMimeType());
         
-        f = (ContentTypeField) Field.parse("content-type:   TeXt / html   ");
+        f = (ContentTypeField) AbstractField.parse("content-type:   TeXt / html   ");
         assertEquals("text/html", f.getMimeType());
         
-        f = (ContentTypeField) Field.parse("CONTENT-TYPE:   x-app/yada ;"
+        f = (ContentTypeField) AbstractField.parse("CONTENT-TYPE:   x-app/yada ;"
                                                     + "  param = yada");
         assertEquals("x-app/yada", f.getMimeType());
         
-        f = (ContentTypeField) Field.parse("CONTENT-TYPE:   yada");
+        f = (ContentTypeField) AbstractField.parse("CONTENT-TYPE:   yada");
         assertEquals("", f.getMimeType());
     }
     
@@ -61,47 +61,47 @@
         ContentTypeField child = null;
         ContentTypeField parent = null;
         
-        child = (ContentTypeField) Field.parse("Content-Type: child/type");
-        parent = (ContentTypeField) Field.parse("Content-Type: parent/type");
+        child = (ContentTypeField) AbstractField.parse("Content-Type: child/type");
+        parent = (ContentTypeField) AbstractField.parse("Content-Type: parent/type");
         assertEquals("child/type", ContentTypeField.getMimeType(child, parent));
         
         child = null;
-        parent = (ContentTypeField) Field.parse("Content-Type: parent/type");
+        parent = (ContentTypeField) AbstractField.parse("Content-Type: parent/type");
         assertEquals("text/plain", ContentTypeField.getMimeType(child, parent));
-        parent = (ContentTypeField) Field.parse("Content-Type: multipart/digest");
+        parent = (ContentTypeField) AbstractField.parse("Content-Type: multipart/digest");
         assertEquals("message/rfc822", ContentTypeField.getMimeType(child, parent));
         
-        child = (ContentTypeField) Field.parse("Content-Type:");
-        parent = (ContentTypeField) Field.parse("Content-Type: parent/type");
+        child = (ContentTypeField) AbstractField.parse("Content-Type:");
+        parent = (ContentTypeField) AbstractField.parse("Content-Type: parent/type");
         assertEquals("text/plain", ContentTypeField.getMimeType(child, parent));
-        parent = (ContentTypeField) Field.parse("Content-Type: multipart/digest");
+        parent = (ContentTypeField) AbstractField.parse("Content-Type: multipart/digest");
         assertEquals("message/rfc822", ContentTypeField.getMimeType(child, parent));
     }
     
     public void testGetCharsetStatic() throws Exception {
         ContentTypeField f = null;
         
-        f = (ContentTypeField) Field.parse("Content-Type: some/type; charset=iso8859-1");
+        f = (ContentTypeField) AbstractField.parse("Content-Type: some/type; charset=iso8859-1");
         assertEquals("iso8859-1", ContentTypeField.getCharset(f));
         
-        f = (ContentTypeField) Field.parse("Content-Type: some/type;");
+        f = (ContentTypeField) AbstractField.parse("Content-Type: some/type;");
         assertEquals("us-ascii", ContentTypeField.getCharset(f));
     }
     
     public void testGetParameter() throws Exception {
         ContentTypeField f = null;
         
-        f = (ContentTypeField) Field.parse("CONTENT-TYPE:   text / html ;"
+        f = (ContentTypeField) AbstractField.parse("CONTENT-TYPE:   text / html ;"
                                                 + "  boundary=yada yada");
         assertEquals("yada", f.getParameter("boundary"));
         
-        f = (ContentTypeField) Field.parse("Content-Type: x-app/yada;"
+        f = (ContentTypeField) AbstractField.parse("Content-Type: x-app/yada;"
                                                 + "  boUNdarY= \"ya:\\\"*da\"; "
                                                 + "\tcharset\t =  us-ascii");
         assertEquals("ya:\"*da", f.getParameter("boundary"));
         assertEquals("us-ascii", f.getParameter("charset"));
         
-        f = (ContentTypeField) Field.parse("Content-Type: x-app/yada;  "
+        f = (ContentTypeField) AbstractField.parse("Content-Type: x-app/yada;  "
                             + "boUNdarY= \"ya \\\"\\\"\tda \\\"\"; "
                             + "\tcharset\t =  \"\\\"hepp\\\"  =us\t-ascii\"");
         assertEquals("ya \"\"\tda \"", f.getParameter("boundary"));
Index: src/test/java/org/apache/james/mime4j/field/FieldTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/FieldTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/FieldTest.java	(working copy)
@@ -22,8 +22,9 @@
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.field.ContentTransferEncodingField;
 import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.UnstructuredField;
+import org.apache.james.mime4j.parser.Field;
 
 import junit.framework.TestCase;
 
@@ -32,14 +33,14 @@
     public void testGetName() throws Exception {
         Field f = null;
         
-        f = Field.parse("Subject: Yada yada yada");
+        f = AbstractField.parse("Subject: Yada yada yada");
         assertEquals("Testing simple field", "Subject", f.getName());
         
-        f = Field.parse("X-yada-yada: Yada yada yada");
+        f = AbstractField.parse("X-yada-yada: Yada yada yada");
         assertEquals("Testing an X- field", "X-yada-yada", f.getName());
         
         try {
-            f = Field.parse("Yada yada yada");
+            f = AbstractField.parse("Yada yada yada");
             fail("MimeException not thrown when using an invalid field");
         } catch (MimeException e) {
         }
@@ -48,13 +49,13 @@
     public void testParse() throws Exception {
         Field f = null;
         
-        f = Field.parse("Subject: Yada yada yada");
+        f = AbstractField.parse("Subject: Yada yada yada");
         assertTrue("Field should be UnstructuredField", 
                         f instanceof UnstructuredField);
-        f = Field.parse("Content-Type: text/plain");
+        f = AbstractField.parse("Content-Type: text/plain");
         assertTrue("Field should be ContentTypeField", 
                         f instanceof ContentTypeField);
-        f = Field.parse("Content-Transfer-Encoding: 7bit");
+        f = AbstractField.parse("Content-Transfer-Encoding: 7bit");
         assertTrue("Field should be ContentTransferEncodingField", 
                         f instanceof ContentTransferEncodingField);
     }
Index: src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/ContentDispositionFieldTest.java	(working copy)
@@ -36,7 +36,7 @@
     public void testDispositionTypeWithSemiColonNoParams() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline;");
         assertEquals("inline", f.getDispositionType());
     }
@@ -44,37 +44,37 @@
     public void testGetDispositionType() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertEquals("attachment", f.getDispositionType());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("content-disposition:   InLiNe   ");
         assertEquals("inline", f.getDispositionType());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("CONTENT-DISPOSITION:   x-yada ;" + "  param = yada");
         assertEquals("x-yada", f.getDispositionType());
 
-        f = (ContentDispositionField) Field.parse("CONTENT-DISPOSITION:   ");
+        f = (ContentDispositionField) AbstractField.parse("CONTENT-DISPOSITION:   ");
         assertEquals("", f.getDispositionType());
     }
 
     public void testGetParameter() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("CONTENT-DISPOSITION:   inline ;"
                         + "  filename=yada yada");
         assertEquals("yada", f.getParameter("filename"));
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: x-yada;"
                         + "  fileNAme= \"ya:\\\"*da\"; " + "\tSIZE\t =  1234");
         assertEquals("ya:\"*da", f.getParameter("filename"));
         assertEquals("1234", f.getParameter("size"));
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: x-yada;  "
                         + "fileNAme= \"ya \\\"\\\"\tda \\\"\"; "
                         + "\tx-Yada\t =  \"\\\"hepp\\\"  =us\t-ascii\"");
@@ -85,19 +85,19 @@
     public void testIsDispositionType() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field.parse("Content-Disposition:INline");
+        f = (ContentDispositionField) AbstractField.parse("Content-Disposition:INline");
         assertTrue(f.isDispositionType("InLiNe"));
         assertFalse(f.isDispositionType("NiLiNe"));
         assertTrue(f.isInline());
         assertFalse(f.isAttachment());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertTrue(f.isDispositionType("ATTACHMENT"));
         assertFalse(f.isInline());
         assertTrue(f.isAttachment());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: x-something");
         assertTrue(f.isDispositionType("x-SomeThing"));
         assertFalse(f.isInline());
@@ -107,19 +107,19 @@
     public void testGetFilename() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; filename=yada.txt");
         assertEquals("yada.txt", f.getFilename());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; filename=yada yada.txt");
         assertEquals("yada", f.getFilename());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; filename=\"yada yada.txt\"");
         assertEquals("yada yada.txt", f.getFilename());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline");
         assertNull(f.getFilename());
     }
@@ -127,17 +127,17 @@
     public void testGetCreationDate() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "creation-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
         assertEquals(new Date(0), f.getCreationDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "creation-date=Tue, 01 Jan 1970 00:00:00 +0000");
         assertNull(f.getCreationDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertNull(f.getCreationDate());
     }
@@ -145,22 +145,22 @@
     public void testGetModificationDate() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "modification-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
         assertEquals(new Date(0), f.getModificationDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\"");
         assertEquals(new Date(855782991000l), f.getModificationDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "modification-date=yesterday");
         assertNull(f.getModificationDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertNull(f.getModificationDate());
     }
@@ -168,16 +168,16 @@
     public void testGetReadDate() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; "
                         + "read-date=\"Tue, 01 Jan 1970 00:00:00 +0000\"");
         assertEquals(new Date(0), f.getReadDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: inline; read-date=");
         assertNull(f.getReadDate());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertNull(f.getReadDate());
     }
@@ -185,23 +185,23 @@
     public void testGetSize() throws Exception {
         ContentDispositionField f = null;
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment; size=0");
         assertEquals(0, f.getSize());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment; size=matters");
         assertEquals(-1, f.getSize());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment");
         assertEquals(-1, f.getSize());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment; size=-12");
         assertEquals(-1, f.getSize());
 
-        f = (ContentDispositionField) Field
+        f = (ContentDispositionField) AbstractField
                 .parse("Content-Disposition: attachment; size=12");
         assertEquals(12, f.getSize());
     }
Index: src/test/java/org/apache/james/mime4j/field/FieldsTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/FieldsTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/FieldsTest.java	(working copy)
@@ -200,7 +200,7 @@
     }
 
     public void testMessageId() throws Exception {
-        Field messageId = Fields.messageId("acme.org");
+        AbstractField messageId = Fields.messageId("acme.org");
 
         String raw = messageId.getRaw();
         assertTrue(raw.startsWith("Message-ID: <Mime4j."));
Index: src/test/java/org/apache/james/mime4j/field/ContentTransferEncodingFieldTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/ContentTransferEncodingFieldTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/ContentTransferEncodingFieldTest.java	(working copy)
@@ -20,7 +20,7 @@
 package org.apache.james.mime4j.field;
 
 import org.apache.james.mime4j.field.ContentTransferEncodingField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 
 import junit.framework.TestCase;
 
@@ -30,19 +30,19 @@
         ContentTransferEncodingField f = null;
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding: 8bit");
+                    AbstractField.parse("Content-Transfer-Encoding: 8bit");
         assertEquals("8bit", f.getEncoding());
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding:    BaSE64   ");
+                    AbstractField.parse("Content-Transfer-Encoding:    BaSE64   ");
         assertEquals("base64", f.getEncoding());
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding:       ");
+                    AbstractField.parse("Content-Transfer-Encoding:       ");
         assertEquals("", f.getEncoding());
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding:");
+                    AbstractField.parse("Content-Transfer-Encoding:");
         assertEquals("", f.getEncoding());
     }
     
@@ -50,18 +50,18 @@
         ContentTransferEncodingField f = null;
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding: 8bit");
+                    AbstractField.parse("Content-Transfer-Encoding: 8bit");
         assertEquals("8bit", ContentTransferEncodingField.getEncoding(f));
         
         f = null;
         assertEquals("7bit", ContentTransferEncodingField.getEncoding(f));
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding:       ");
+                    AbstractField.parse("Content-Transfer-Encoding:       ");
         assertEquals("7bit", ContentTransferEncodingField.getEncoding(f));
         
         f = (ContentTransferEncodingField) 
-                    Field.parse("Content-Transfer-Encoding:");
+                    AbstractField.parse("Content-Transfer-Encoding:");
         assertEquals("7bit", ContentTransferEncodingField.getEncoding(f));
     }
 
Index: src/test/java/org/apache/james/mime4j/field/UnstructuredFieldTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/field/UnstructuredFieldTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/field/UnstructuredFieldTest.java	(working copy)
@@ -19,7 +19,7 @@
 
 package org.apache.james.mime4j.field;
 
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.UnstructuredField;
 
 import junit.framework.TestCase;
@@ -29,13 +29,13 @@
     public void testGetBody() throws Exception {
         UnstructuredField f = null;
         
-        f = (UnstructuredField) Field.parse("Subject: Yada\r\n yada yada\r\n");
+        f = (UnstructuredField) AbstractField.parse("Subject: Yada\r\n yada yada\r\n");
         assertEquals("Testing folding value 1", "Yada yada yada", f.getValue());
         
-        f = (UnstructuredField) Field.parse("Subject:  \r\n\tyada");
+        f = (UnstructuredField) AbstractField.parse("Subject:  \r\n\tyada");
         assertEquals("Testing folding value 2", " \tyada", f.getValue());
         
-        f = (UnstructuredField) Field.parse("Subject:yada");
+        f = (UnstructuredField) AbstractField.parse("Subject:yada");
         assertEquals("Testing value without a leading ' '", "yada", f.getValue());
     }
 
Index: src/test/java/org/apache/james/mime4j/message/CopyConstructorTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/CopyConstructorTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/CopyConstructorTest.java	(working copy)
@@ -22,7 +22,8 @@
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
+import org.apache.james.mime4j.parser.Field;
 
 import junit.framework.TestCase;
 
@@ -160,9 +161,9 @@
     }
 
     public void testCopyHeader() throws Exception {
-        Field f1 = Field.parse("name1: value1");
-        Field f2 = Field.parse("name2: value");
-        Field f3 = Field.parse("name1: value2");
+        Field f1 = AbstractField.parse("name1: value1");
+        Field f2 = AbstractField.parse("name2: value");
+        Field f3 = AbstractField.parse("name1: value2");
 
         Header original = new Header();
         original.addField(f1);
Index: src/test/java/org/apache/james/mime4j/message/MessageParserTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MessageParserTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/MessageParserTest.java	(working copy)
@@ -20,7 +20,7 @@
 package org.apache.james.mime4j.message;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.parser.MimeEntityConfig;
 import org.apache.james.mime4j.util.CharsetUtil;
 import org.apache.log4j.BasicConfigurator;
Index: src/test/java/org/apache/james/mime4j/message/MessageTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MessageTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/MessageTest.java	(working copy)
@@ -34,7 +34,7 @@
 import junit.framework.TestCase;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.address.Group;
 import org.apache.james.mime4j.field.address.Mailbox;
 
@@ -54,13 +54,13 @@
         headerMultipartDigest = new Header();
         
         headerTextPlain.addField(
-                Field.parse("Content-Type: text/plain"));
+                AbstractField.parse("Content-Type: text/plain"));
         headerMessageRFC822.addField(
-                Field.parse("Content-Type: message/RFC822"));
+                AbstractField.parse("Content-Type: message/RFC822"));
         headerMultipartMixed.addField(
-                Field.parse("Content-Type: multipart/mixed; boundary=foo"));
+                AbstractField.parse("Content-Type: multipart/mixed; boundary=foo"));
         headerMultipartDigest.addField(
-                Field.parse("Content-Type: multipart/digest; boundary=foo"));
+                AbstractField.parse("Content-Type: multipart/digest; boundary=foo"));
     }
 
     public void testGetMimeType() {
@@ -147,7 +147,7 @@
         byte[] inputByte = getRawMessageAsByteArray();
 
         Message m = new Message(new ByteArrayInputStream(inputByte));
-        m.getHeader().addField(Field.parse(testheader));
+        m.getHeader().addField(AbstractField.parse(testheader));
 
         assertEquals("header added", m.getHeader().getField(headerName)
                 .getBody(), headerValue);
@@ -167,7 +167,7 @@
 
         String id = "<msg17@localhost>";
         Header header = new Header();
-        header.setField(Field.parse("Message-ID", id));
+        header.setField(AbstractField.parse("Message-ID", id));
         m.setHeader(header);
         assertEquals(id, m.getMessageId());
     }
@@ -188,11 +188,11 @@
 
         String subject = "testing 1 2";
         Header header = new Header();
-        header.setField(Field.parse("Subject", subject));
+        header.setField(AbstractField.parse("Subject", subject));
         m.setHeader(header);
         assertEquals(subject, m.getSubject());
 
-        header.setField(Field.parse("Subject", "=?windows-1252?Q?99_=80?="));
+        header.setField(AbstractField.parse("Subject", "=?windows-1252?Q?99_=80?="));
         assertEquals("99 \u20ac", m.getSubject());
     }
 
@@ -213,7 +213,7 @@
         assertNull(m.getDate());
 
         Header header = new Header();
-        header.setField(Field.parse("Date", "Thu, 1 Jan 1970 05:30:00 +0530"));
+        header.setField(AbstractField.parse("Date", "Thu, 1 Jan 1970 05:30:00 +0530"));
         m.setHeader(header);
 
         assertEquals(new Date(0), m.getDate());
@@ -236,7 +236,7 @@
         assertNull(m.getSender());
 
         Header header = new Header();
-        header.setField(Field.parse("Sender", "john.doe@example.net"));
+        header.setField(AbstractField.parse("Sender", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", m.getSender().getAddress());
@@ -258,7 +258,7 @@
         assertNull(m.getFrom());
 
         Header header = new Header();
-        header.setField(Field.parse("From", "john.doe@example.net"));
+        header.setField(AbstractField.parse("From", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", m.getFrom().get(0).getAddress());
@@ -291,7 +291,7 @@
         assertNull(m.getTo());
 
         Header header = new Header();
-        header.setField(Field.parse("To", "john.doe@example.net"));
+        header.setField(AbstractField.parse("To", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", ((Mailbox) m.getTo().get(0))
@@ -329,7 +329,7 @@
         assertNull(m.getCc());
 
         Header header = new Header();
-        header.setField(Field.parse("Cc", "john.doe@example.net"));
+        header.setField(AbstractField.parse("Cc", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", ((Mailbox) m.getCc().get(0))
@@ -367,7 +367,7 @@
         assertNull(m.getBcc());
 
         Header header = new Header();
-        header.setField(Field.parse("Bcc", "john.doe@example.net"));
+        header.setField(AbstractField.parse("Bcc", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", ((Mailbox) m.getBcc().get(0))
@@ -405,7 +405,7 @@
         assertNull(m.getReplyTo());
 
         Header header = new Header();
-        header.setField(Field.parse("Reply-To", "john.doe@example.net"));
+        header.setField(AbstractField.parse("Reply-To", "john.doe@example.net"));
         m.setHeader(header);
 
         assertEquals("john.doe@example.net", ((Mailbox) m.getReplyTo().get(0))
Index: src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java	(working copy)
@@ -23,7 +23,7 @@
 
 import junit.framework.TestCase;
 
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 
 public class MultipartFormTest extends TestCase {
 
@@ -33,24 +33,24 @@
         Message message = new Message();
         Header header = new Header();
         header.addField(
-                Field.parse("Content-Type: multipart/form-data; boundary=foo"));
+                AbstractField.parse("Content-Type: multipart/form-data; boundary=foo"));
         message.setHeader(header);
         
         Multipart multipart = new Multipart("alternative");
         multipart.setParent(message);
         BodyPart p1 = new BodyPart();
         Header h1 = new Header();
-        h1.addField(Field.parse("Content-Type: text/plain"));
+        h1.addField(AbstractField.parse("Content-Type: text/plain"));
         p1.setHeader(h1);
         p1.setBody(bodyFactory.textBody("this stuff"));
         BodyPart p2 = new BodyPart();
         Header h2 = new Header();
-        h2.addField(Field.parse("Content-Type: text/plain"));
+        h2.addField(AbstractField.parse("Content-Type: text/plain"));
         p2.setHeader(h2);
         p2.setBody(bodyFactory.textBody("that stuff"));
         BodyPart p3 = new BodyPart();
         Header h3 = new Header();
-        h3.addField(Field.parse("Content-Type: text/plain"));
+        h3.addField(AbstractField.parse("Content-Type: text/plain"));
         p3.setHeader(h3);
         p3.setBody(bodyFactory.textBody("all kind of stuff"));
 
Index: src/test/java/org/apache/james/mime4j/message/HeaderTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/HeaderTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/HeaderTest.java	(working copy)
@@ -23,7 +23,8 @@
 
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.james.mime4j.MimeIOException;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.CharsetUtil;
 
 public class HeaderTest extends TestCase {
@@ -34,8 +35,8 @@
 
     public void testHeader() throws Exception {
         Header header = new Header();
-        header.addField(Field.parse(SUBJECT));
-        header.addField(Field.parse(TO));
+        header.addField(AbstractField.parse(SUBJECT));
+        header.addField(AbstractField.parse(TO));
 
         assertNotNull("Subject found", header.getField("Subject"));
         assertNotNull("To found", header.getField("To"));
@@ -49,7 +50,7 @@
     public void testWriteInStrictMode() throws Exception {
         String hello = SWISS_GERMAN_HELLO;
         Header header = new Header();
-        header.addField(Field.parse("Hello: " + hello));
+        header.addField(AbstractField.parse("Hello: " + hello));
         
         Field field = header.getField("Hello");
         assertNotNull(field);
@@ -74,8 +75,8 @@
     public void testWriteInLenientMode() throws Exception {
         String hello = SWISS_GERMAN_HELLO;
         Header header = new Header();
-        header.addField(Field.parse("Hello: " + hello));
-        header.addField(Field.parse("Content-type: text/plain; charset=" + 
+        header.addField(AbstractField.parse("Hello: " + hello));
+        header.addField(AbstractField.parse("Content-type: text/plain; charset=" + 
                 CharsetUtil.ISO_8859_1.name()));
         
         Field field = header.getField("Hello");
@@ -93,9 +94,9 @@
     
     public void testRemoveFields() throws Exception {
         Header header = new Header();
-        header.addField(Field.parse("Received: from foo by bar for james"));
-        header.addField(Field.parse("Content-type: text/plain; charset=US-ASCII"));
-        header.addField(Field.parse("ReCeIvEd: from bar by foo for james"));
+        header.addField(AbstractField.parse("Received: from foo by bar for james"));
+        header.addField(AbstractField.parse("Content-type: text/plain; charset=US-ASCII"));
+        header.addField(AbstractField.parse("ReCeIvEd: from bar by foo for james"));
 
         assertEquals(3, header.getFields().size());
         assertEquals(2, header.getFields("received").size());
@@ -112,9 +113,9 @@
 
     public void testRemoveNonExistantField() throws Exception {
         Header header = new Header();
-        header.addField(Field.parse("Received: from foo by bar for james"));
-        header.addField(Field.parse("Content-type: text/plain; charset=US-ASCII"));
-        header.addField(Field.parse("ReCeIvEd: from bar by foo for james"));
+        header.addField(AbstractField.parse("Received: from foo by bar for james"));
+        header.addField(AbstractField.parse("Content-type: text/plain; charset=US-ASCII"));
+        header.addField(AbstractField.parse("ReCeIvEd: from bar by foo for james"));
 
         assertEquals(0, header.removeFields("noSuchField"));
 
@@ -125,12 +126,12 @@
 
     public void testSetField() throws Exception {
         Header header = new Header();
-        header.addField(Field.parse("From: mime4j@james.apache.org"));
-        header.addField(Field.parse("Received: from foo by bar for james"));
-        header.addField(Field.parse("Content-type: text/plain; charset=US-ASCII"));
-        header.addField(Field.parse("ReCeIvEd: from bar by foo for james"));
+        header.addField(AbstractField.parse("From: mime4j@james.apache.org"));
+        header.addField(AbstractField.parse("Received: from foo by bar for james"));
+        header.addField(AbstractField.parse("Content-type: text/plain; charset=US-ASCII"));
+        header.addField(AbstractField.parse("ReCeIvEd: from bar by foo for james"));
 
-        header.setField(Field.parse("received: from nobody by noone for james"));
+        header.setField(AbstractField.parse("received: from nobody by noone for james"));
 
         assertEquals(3, header.getFields().size());
         assertEquals(1, header.getFields("received").size());
@@ -142,11 +143,11 @@
 
     public void testSetNonExistantField() throws Exception {
         Header header = new Header();
-        header.addField(Field.parse("Received: from foo by bar for james"));
-        header.addField(Field.parse("Content-type: text/plain; charset=US-ASCII"));
-        header.addField(Field.parse("ReCeIvEd: from bar by foo for james"));
+        header.addField(AbstractField.parse("Received: from foo by bar for james"));
+        header.addField(AbstractField.parse("Content-type: text/plain; charset=US-ASCII"));
+        header.addField(AbstractField.parse("ReCeIvEd: from bar by foo for james"));
 
-        header.setField(Field.parse("Message-ID: <msg9901@apache.org>"));
+        header.setField(AbstractField.parse("Message-ID: <msg9901@apache.org>"));
 
         assertEquals(4, header.getFields().size());
         assertEquals(1, header.getFields("message-id").size());
Index: src/test/java/org/apache/james/mime4j/message/EntityTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/message/EntityTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/message/EntityTest.java	(working copy)
@@ -19,7 +19,7 @@
 
 package org.apache.james.mime4j.message;
 
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.message.Entity;
 
 import junit.framework.TestCase;
@@ -32,7 +32,7 @@
         assertNull(entity.getDispositionType());
 
         Header header = new Header();
-        header.setField(Field.parse("Content-Disposition", "inline"));
+        header.setField(AbstractField.parse("Content-Disposition", "inline"));
         entity.setHeader(header);
 
         assertEquals("inline", entity.getDispositionType());
@@ -62,7 +62,7 @@
         assertNull(entity.getFilename());
 
         Header header = new Header();
-        header.setField(Field.parse("Content-Disposition",
+        header.setField(AbstractField.parse("Content-Disposition",
                 "attachment; filename=\"some file.dat\""));
         entity.setHeader(header);
 
Index: src/test/java/org/apache/james/mime4j/parser/MimeStreamParserTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/parser/MimeStreamParserTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/parser/MimeStreamParserTest.java	(working copy)
@@ -139,8 +139,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
@@ -163,8 +163,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
@@ -187,8 +187,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
@@ -248,8 +248,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
@@ -297,7 +297,7 @@
             }
 
             @Override
-            public void field(String fieldData) {
+            public void field(Field field) {
                 fail("field shouldn't be called for empty stream");
             }
 
@@ -340,7 +340,7 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
+            public void field(Field field) {
                 fail("No fields should be reported");
             }
             @Override
@@ -371,8 +371,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
             @Override
             public void body(BodyDescriptor bd, InputStream is) throws IOException {
@@ -399,8 +399,8 @@
         MimeStreamParser parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
@@ -418,8 +418,8 @@
         parser = new MimeStreamParser();
         parser.setContentHandler(new AbstractContentHandler() {
             @Override
-            public void field(String fieldData) {
-                assertEquals(expected.removeFirst(), fieldData);
+            public void field(Field field) {
+                assertEquals(expected.removeFirst(), field.getRaw());
             }
         });
         
Index: src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java
===================================================================
--- src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/parser/MimeEntityTest.java	(working copy)
@@ -63,33 +63,33 @@
         assertEquals(EntityStates.T_START_HEADER, entity.getState());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("To", entity.getFieldName());
-        assertEquals(" Road Runner <runner@example.org>", entity.getFieldValue());
+        assertEquals("To", entity.getField().getName());
+        assertEquals(" Road Runner <runner@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("From", entity.getFieldName());
-        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getFieldValue());
+        assertEquals("From", entity.getField().getName());
+        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Date", entity.getFieldName());
-        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getFieldValue());
+        assertEquals("Date", entity.getField().getName());
+        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Subject", entity.getFieldName());
-        assertEquals(" Mail", entity.getFieldValue());
+        assertEquals("Subject", entity.getField().getName());
+        assertEquals(" Mail", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Content-Type", entity.getFieldName());
-        assertEquals(" text/plain", entity.getFieldValue());
+        assertEquals("Content-Type", entity.getField().getName());
+        assertEquals(" text/plain", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_END_HEADER, entity.getState());
         try {
-            entity.getFieldName();
+            entity.getField().getName();
             fail("IllegalStateException should have been thrown");
         } catch (IllegalStateException expected) {
         }
         try {
-            entity.getFieldValue();
+            entity.getField().getBody();
             fail("IllegalStateException should have been thrown");
         } catch (IllegalStateException expected) {
         }
@@ -149,24 +149,24 @@
         assertEquals(EntityStates.T_START_HEADER, entity.getState());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("To", entity.getFieldName());
-        assertEquals(" Road Runner <runner@example.org>", entity.getFieldValue());
+        assertEquals("To", entity.getField().getName());
+        assertEquals(" Road Runner <runner@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("From", entity.getFieldName());
-        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getFieldValue());
+        assertEquals("From", entity.getField().getName());
+        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Date", entity.getFieldName());
-        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getFieldValue());
+        assertEquals("Date", entity.getField().getName());
+        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Subject", entity.getFieldName());
-        assertEquals(" Mail", entity.getFieldValue());
+        assertEquals("Subject", entity.getField().getName());
+        assertEquals(" Mail", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Content-Type", entity.getFieldName());
-        assertEquals(" multipart/mixed;boundary=1729", entity.getFieldValue());
+        assertEquals("Content-Type", entity.getField().getName());
+        assertEquals(" multipart/mixed;boundary=1729", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_END_HEADER, entity.getState());
         entity.advance();
@@ -183,8 +183,8 @@
         assertEquals(EntityStates.T_START_HEADER, p1.getState());
         p1.advance();
         assertEquals(EntityStates.T_FIELD, p1.getState());
-        assertEquals("Content-Type", p1.getFieldName());
-        assertEquals(" text/plain; charset=US-ASCII", p1.getFieldValue());
+        assertEquals("Content-Type", p1.getField().getName());
+        assertEquals(" text/plain; charset=US-ASCII", p1.getField().getBody());
         p1.advance();
         assertEquals(EntityStates.T_END_HEADER, p1.getState());
         p1.advance();
@@ -203,8 +203,8 @@
         assertEquals(EntityStates.T_START_HEADER, p2.getState());
         p2.advance();
         assertEquals(EntityStates.T_FIELD, p2.getState());
-        assertEquals("Content-Type", p2.getFieldName());
-        assertEquals(" text/plain; charset=US-ASCII", p2.getFieldValue());
+        assertEquals("Content-Type", p2.getField().getName());
+        assertEquals(" text/plain; charset=US-ASCII", p2.getField().getBody());
         p2.advance();
         assertEquals(EntityStates.T_END_HEADER, p2.getState());
         p2.advance();
@@ -264,24 +264,24 @@
         assertEquals(EntityStates.T_START_HEADER, entity.getState());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("To", entity.getFieldName());
-        assertEquals(" Road Runner <runner@example.org>", entity.getFieldValue());
+        assertEquals("To", entity.getField().getName());
+        assertEquals(" Road Runner <runner@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("From", entity.getFieldName());
-        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getFieldValue());
+        assertEquals("From", entity.getField().getName());
+        assertEquals(" Wile E. Cayote <wile@example.org>", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Date", entity.getFieldName());
-        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getFieldValue());
+        assertEquals("Date", entity.getField().getName());
+        assertEquals(" Tue, 12 Feb 2008 17:34:09 +0000 (GMT)", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Subject", entity.getFieldName());
-        assertEquals(" Mail", entity.getFieldValue());
+        assertEquals("Subject", entity.getField().getName());
+        assertEquals(" Mail", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_FIELD, entity.getState());
-        assertEquals("Content-Type", entity.getFieldName());
-        assertEquals(" multipart/mixed;boundary=1729", entity.getFieldValue());
+        assertEquals("Content-Type", entity.getField().getName());
+        assertEquals(" multipart/mixed;boundary=1729", entity.getField().getBody());
         entity.advance();
         assertEquals(EntityStates.T_END_HEADER, entity.getState());
         entity.advance();
@@ -297,8 +297,6 @@
         assertEquals(EntityStates.T_RAW_ENTITY, p1.getState());
         assertNull(p1.getBodyDescriptor());
         assertNull(p1.getField());
-        assertNull(p1.getFieldName());
-        assertNull(p1.getFieldValue());
         assertEquals(
                 "Content-Type: text/plain; charset=US-ASCII\r\n" +
                 "\r\n" +
@@ -312,8 +310,6 @@
         assertEquals(EntityStates.T_RAW_ENTITY, p2.getState());
         assertNull(p2.getBodyDescriptor());
         assertNull(p2.getField());
-        assertNull(p2.getFieldName());
-        assertNull(p2.getFieldValue());
         assertEquals(
                 "Content-Type: text/plain; charset=US-ASCII\r\n" +
                 "\r\n" +
Index: src/test/java/org/apache/james/mime4j/parser/TestHandler.java
===================================================================
--- src/test/java/org/apache/james/mime4j/parser/TestHandler.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/parser/TestHandler.java	(working copy)
@@ -90,8 +90,8 @@
     public void startHeader() {
         sb.append("<header>\r\n");
     }
-    public void field(String fieldData) {
-        sb.append("<field>\r\n" + escape(fieldData) + "</field>\r\n");
+    public void field(Field field) {
+        sb.append("<field>\r\n" + escape(field.getRaw()) + "</field>\r\n");
     }
     public void endHeader() {
         sb.append("</header>\r\n");
Index: src/test/java/org/apache/james/mime4j/descriptor/BaseTestForBodyDescriptors.java
===================================================================
--- src/test/java/org/apache/james/mime4j/descriptor/BaseTestForBodyDescriptors.java	(revision 744866)
+++ src/test/java/org/apache/james/mime4j/descriptor/BaseTestForBodyDescriptors.java	(working copy)
@@ -21,6 +21,7 @@
 
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
 import org.apache.james.mime4j.descriptor.MutableBodyDescriptor;
+import org.apache.james.mime4j.field.AbstractField;
 
 import junit.framework.TestCase;
 
@@ -34,25 +35,25 @@
         MutableBodyDescriptor bd = null;
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain; charset=ISO-8859-1; "
-                + "boundary=foo; param1=value1; param2=value2; param3=value3");
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain; charset=ISO-8859-1; "
+                + "boundary=foo; param1=value1; param2=value2; param3=value3"));
         assertEquals(3, bd.getContentTypeParameters().size());
         assertEquals("value1", bd.getContentTypeParameters().get("param1"));
         assertEquals("value2", bd.getContentTypeParameters().get("param2"));
         assertEquals("value3", bd.getContentTypeParameters().get("param3"));
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain; param1=value1; param2=value2;"
-                     + " param3=value3");
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain; param1=value1; param2=value2;"
+                     + " param3=value3"));
         assertEquals(3, bd.getContentTypeParameters().size());
         assertEquals("value1", bd.getContentTypeParameters().get("param1"));
         assertEquals("value2", bd.getContentTypeParameters().get("param2"));
         assertEquals("value3", bd.getContentTypeParameters().get("param3"));
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain; "
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain; "
                 + "param1= \" value with\tspaces \" ; "
-                + "param2=\"\\\"value4 with escaped \\\" \\\"\";");
+                + "param2=\"\\\"value4 with escaped \\\" \\\"\";"));
         assertEquals(2, bd.getContentTypeParameters().size());
         assertEquals(" value with\tspaces ", bd.getContentTypeParameters().get("param1"));
         assertEquals("\"value4 with escaped \" \"", bd.getContentTypeParameters().get("param2"));
@@ -62,7 +63,7 @@
          * The parameter value should be \n\"
          */
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain; param=\"\\n\\\\\\\"\"");
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain; param=\"\\n\\\\\\\"\""));
         assertEquals(1, bd.getContentTypeParameters().size());
         assertEquals("\\n\\\"", bd.getContentTypeParameters().get("param"));
     }
@@ -74,10 +75,10 @@
          * Make sure that only the first Content-Type header added is used.
          */
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain; charset=ISO-8859-1");
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain; charset=ISO-8859-1"));
         assertEquals("text/plain", bd.getMimeType());
         assertEquals("iso-8859-1", bd.getCharset());
-        bd.addField("Content-Type ", "text/html; charset=us-ascii");
+        bd.addField(AbstractField.parse("Content-Type ", "text/html; charset=us-ascii"));
         assertEquals("text/plain", bd.getMimeType());
         assertEquals("iso-8859-1", bd.getCharset());
     }
@@ -86,32 +87,32 @@
         MutableBodyDescriptor bd = null;
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/PLAIN");
+        bd.addField(AbstractField.parse("Content-Type ", "text/PLAIN"));
         assertEquals("text/plain", bd.getMimeType());
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/PLAIN;");
+        bd.addField(AbstractField.parse("Content-Type ", "text/PLAIN;"));
         assertEquals("text/plain", bd.getMimeType());
         
         bd = newBodyDescriptor();
-        bd.addField("content-type", "   TeXt / html   ");
+        bd.addField(AbstractField.parse("content-type", "   TeXt / html   "));
         assertEquals("text/html", bd.getMimeType());
         
         bd = newBodyDescriptor();
-        bd.addField("CONTENT-TYPE", "   x-app/yada ;  param = yada");
+        bd.addField(AbstractField.parse("CONTENT-TYPE", "   x-app/yada ;  param = yada"));
         assertEquals("x-app/yada", bd.getMimeType());
         
         bd = newBodyDescriptor();
-        bd.addField("CONTENT-TYPE", "   yada");
+        bd.addField(AbstractField.parse("CONTENT-TYPE", "   yada"));
         assertEquals("text/plain", bd.getMimeType());
         
         /*
          * Make sure that only the first Content-Type header added is used.
          */
         bd = newBodyDescriptor();
-        bd.addField("Content-Type ", "text/plain");
+        bd.addField(AbstractField.parse("Content-Type ", "text/plain"));
         assertEquals("text/plain", bd.getMimeType());
-        bd.addField("Content-Type ", "text/html");
+        bd.addField(AbstractField.parse("Content-Type ", "text/html"));
         assertEquals("text/plain", bd.getMimeType());
         
         /*
@@ -121,19 +122,19 @@
         MutableBodyDescriptor parent = null;
         
         parent = newBodyDescriptor();
-        parent.addField("Content-Type", "mutlipart/alternative; boundary=foo");
+        parent.addField(AbstractField.parse("Content-Type", "mutlipart/alternative; boundary=foo"));
         
         child = newBodyDescriptor(parent);
         assertEquals("text/plain", child.getMimeType());
-        child.addField("Content-Type", " child/type");
+        child.addField(AbstractField.parse("Content-Type", " child/type"));
         assertEquals("child/type", child.getMimeType());
         
         parent = newBodyDescriptor();
-        parent.addField("Content-Type", "multipart/digest; boundary=foo");
+        parent.addField(AbstractField.parse("Content-Type", "multipart/digest; boundary=foo"));
         
         child = newBodyDescriptor(parent);
         assertEquals("message/rfc822", child.getMimeType());
-        child.addField("Content-Type", " child/type");
+        child.addField(AbstractField.parse("Content-Type", " child/type"));
         assertEquals("child/type", child.getMimeType());
         
     }
@@ -146,40 +147,40 @@
          */
         bd = newBodyDescriptor();
         assertEquals("us-ascii", bd.getCharset());
-        bd.addField("Content-Type ", "text/type; charset=ISO-8859-1");
+        bd.addField(AbstractField.parse("Content-Type ", "text/type; charset=ISO-8859-1"));
         assertEquals("iso-8859-1", bd.getCharset());
         
         bd = newBodyDescriptor();
         assertEquals("us-ascii", bd.getCharset());
-        bd.addField("Content-Type ", "text/type");
+        bd.addField(AbstractField.parse("Content-Type ", "text/type"));
         assertEquals("us-ascii", bd.getCharset());
         
         /*
          * Test boundary.
          */
         bd = newBodyDescriptor();
-        bd.addField("Content-Type", "text/html; boundary=yada yada");
+        bd.addField(AbstractField.parse("Content-Type", "text/html; boundary=yada yada"));
         assertNull(bd.getBoundary());
 
         bd = newBodyDescriptor();
-        bd.addField("Content-Type", "multipart/yada; boundary=yada");
+        bd.addField(AbstractField.parse("Content-Type", "multipart/yada; boundary=yada"));
         assertEquals("yada", bd.getBoundary());
 
         /*
          * Test some weird parameters.
          */
         bd = newBodyDescriptor();
-        bd.addField("Content-Type", "multipart/yada; boundary=yada yada");
+        bd.addField(AbstractField.parse("Content-Type", "multipart/yada; boundary=yada yada"));
         assertEquals("yada", bd.getBoundary());
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type", "multipart/yada; boUNdarY= ya:*da; \tcharset\t =  big5");
+        bd.addField(AbstractField.parse("Content-Type", "multipart/yada; boUNdarY= ya:*da; \tcharset\t =  big5"));
         assertEquals("ya:*da", bd.getBoundary());
         assertEquals("big5", bd.getCharset());
         
         bd = newBodyDescriptor();
-        bd.addField("Content-Type", "multipart/yada; boUNdarY= \"ya \\\"\\\"\tda \\\"\"; "
-                            + "\tcharset\t =  \"\\\"hepp\\\"  =us\t-ascii\"");
+        bd.addField(AbstractField.parse("Content-Type", "multipart/yada; boUNdarY= \"ya \\\"\\\"\tda \\\"\"; "
+                            + "\tcharset\t =  \"\\\"hepp\\\"  =us\t-ascii\""));
         assertEquals("ya \"\"\tda \"", bd.getBoundary());
         assertEquals("\"hepp\"  =us\t-ascii", bd.getCharset());
         
@@ -191,23 +192,23 @@
         bd = newBodyDescriptor();
         assertEquals(-1, bd.getContentLength());
 
-        bd.addField("Content-Length", "9901");
+        bd.addField(AbstractField.parse("Content-Length", "9901"));
         assertEquals(9901, bd.getContentLength());
 
         // only the first content-length counts
-        bd.addField("Content-Length", "1239901");
+        bd.addField(AbstractField.parse("Content-Length", "1239901"));
         assertEquals(9901, bd.getContentLength());
     }
     
     public void testDoDefaultToUsAsciiWhenUntyped() throws Exception {
         MutableBodyDescriptor descriptor = newBodyDescriptor();
-        descriptor.addField("To", "me@example.org");
+        descriptor.addField(AbstractField.parse("To", "me@example.org"));
         assertEquals("us-ascii", descriptor.getCharset());
     }
 
     public void testDoNotDefaultToUsAsciiForNonTextTypes() throws Exception {
         MutableBodyDescriptor descriptor = newBodyDescriptor();
-        descriptor.addField("Content-Type", "image/png; name=blob.png");
+        descriptor.addField(AbstractField.parse("Content-Type", "image/png; name=blob.png"));
         assertNull(descriptor.getCharset());
     }
 }
Index: src/main/java/org/apache/james/mime4j/field/MailboxField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/MailboxField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/MailboxField.java	(working copy)
@@ -29,7 +29,7 @@
 /**
  * Mailbox field such as <code>Sender</code> or <code>Resent-Sender</code>.
  */
-public class MailboxField extends Field {
+public class MailboxField extends AbstractField {
     private static Log log = LogFactory.getLog(MailboxField.class);
 
     private boolean parsed = false;
@@ -75,7 +75,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new MailboxField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/FieldParser.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/FieldParser.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/FieldParser.java	(working copy)
@@ -19,7 +19,10 @@
 
 package org.apache.james.mime4j.field;
 
+import org.apache.james.mime4j.parser.Field;
+
 public interface FieldParser {
     
     Field parse(final String name, final String body, final String raw);
+    
 }
Index: src/main/java/org/apache/james/mime4j/field/DateTimeField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/DateTimeField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/DateTimeField.java	(working copy)
@@ -31,7 +31,7 @@
 /**
  * Date-time field such as <code>Date</code> or <code>Resent-Date</code>.
  */
-public class DateTimeField extends Field {
+public class DateTimeField extends AbstractField {
     private static Log log = LogFactory.getLog(DateTimeField.class);
 
     private boolean parsed = false;
@@ -80,7 +80,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new DateTimeField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/ContentDispositionField.java	(working copy)
@@ -37,7 +37,7 @@
 /**
  * Represents a <code>Content-Disposition</code> field.
  */
-public class ContentDispositionField extends Field {
+public class ContentDispositionField extends AbstractField {
     private static Log log = LogFactory.getLog(ContentDispositionField.class);
 
     /** The <code>inline</code> disposition type. */
@@ -318,7 +318,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new ContentDispositionField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/DefaultFieldParser.java	(working copy)
@@ -22,29 +22,29 @@
 public class DefaultFieldParser extends DelegatingFieldParser {
     
     public DefaultFieldParser() {
-        setFieldParser(Field.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
-        setFieldParser(Field.CONTENT_TYPE, new ContentTypeField.Parser());
-        setFieldParser(Field.CONTENT_DISPOSITION, new ContentDispositionField.Parser());
+        setFieldParser(AbstractField.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
+        setFieldParser(AbstractField.CONTENT_TYPE, new ContentTypeField.Parser());
+        setFieldParser(AbstractField.CONTENT_DISPOSITION, new ContentDispositionField.Parser());
         
         final DateTimeField.Parser dateTimeParser = new DateTimeField.Parser();
-        setFieldParser(Field.DATE, dateTimeParser);
-        setFieldParser(Field.RESENT_DATE, dateTimeParser);
+        setFieldParser(AbstractField.DATE, dateTimeParser);
+        setFieldParser(AbstractField.RESENT_DATE, dateTimeParser);
         
         final MailboxListField.Parser mailboxListParser = new MailboxListField.Parser();
-        setFieldParser(Field.FROM, mailboxListParser);
-        setFieldParser(Field.RESENT_FROM, mailboxListParser);
+        setFieldParser(AbstractField.FROM, mailboxListParser);
+        setFieldParser(AbstractField.RESENT_FROM, mailboxListParser);
         
         final MailboxField.Parser mailboxParser = new MailboxField.Parser();
-        setFieldParser(Field.SENDER, mailboxParser);
-        setFieldParser(Field.RESENT_SENDER, mailboxParser);
+        setFieldParser(AbstractField.SENDER, mailboxParser);
+        setFieldParser(AbstractField.RESENT_SENDER, mailboxParser);
         
         final AddressListField.Parser addressListParser = new AddressListField.Parser();
-        setFieldParser(Field.TO, addressListParser);
-        setFieldParser(Field.RESENT_TO, addressListParser);
-        setFieldParser(Field.CC, addressListParser);
-        setFieldParser(Field.RESENT_CC, addressListParser);
-        setFieldParser(Field.BCC, addressListParser);
-        setFieldParser(Field.RESENT_BCC, addressListParser);
-        setFieldParser(Field.REPLY_TO, addressListParser);
+        setFieldParser(AbstractField.TO, addressListParser);
+        setFieldParser(AbstractField.RESENT_TO, addressListParser);
+        setFieldParser(AbstractField.CC, addressListParser);
+        setFieldParser(AbstractField.RESENT_CC, addressListParser);
+        setFieldParser(AbstractField.BCC, addressListParser);
+        setFieldParser(AbstractField.RESENT_BCC, addressListParser);
+        setFieldParser(AbstractField.REPLY_TO, addressListParser);
     }
 }
Index: src/main/java/org/apache/james/mime4j/field/Fields.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/Fields.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/Fields.java	(working copy)
@@ -30,10 +30,11 @@
 import org.apache.james.mime4j.codec.EncoderUtil;
 import org.apache.james.mime4j.field.address.Address;
 import org.apache.james.mime4j.field.address.Mailbox;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.MimeUtil;
 
 /**
- * Factory for concrete {@link Field} instances.
+ * Factory for concrete {@link AbstractField} instances.
  */
 public class Fields {
 
@@ -51,7 +52,7 @@
      * @return the newly created <i>Content-Type</i> field.
      */
     public static ContentTypeField contentType(String contentType) {
-        return parse(ContentTypeField.class, Field.CONTENT_TYPE, contentType);
+        return parse(ContentTypeField.class, AbstractField.CONTENT_TYPE, contentType);
     }
 
     /**
@@ -72,7 +73,7 @@
             throw new IllegalArgumentException();
 
         if (parameters == null || parameters.isEmpty()) {
-            return parse(ContentTypeField.class, Field.CONTENT_TYPE, mimeType);
+            return parse(ContentTypeField.class, AbstractField.CONTENT_TYPE, mimeType);
         } else {
             StringBuilder sb = new StringBuilder(mimeType);
             for (Map.Entry<String, String> entry : parameters.entrySet()) {
@@ -97,7 +98,7 @@
     public static ContentTransferEncodingField contentTransferEncoding(
             String contentTransferEncoding) {
         return parse(ContentTransferEncodingField.class,
-                Field.CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
+                AbstractField.CONTENT_TRANSFER_ENCODING, contentTransferEncoding);
     }
 
     /**
@@ -112,7 +113,7 @@
      */
     public static ContentDispositionField contentDisposition(
             String contentDisposition) {
-        return parse(ContentDispositionField.class, Field.CONTENT_DISPOSITION,
+        return parse(ContentDispositionField.class, AbstractField.CONTENT_DISPOSITION,
                 contentDisposition);
     }
 
@@ -135,7 +136,7 @@
 
         if (parameters == null || parameters.isEmpty()) {
             return parse(ContentDispositionField.class,
-                    Field.CONTENT_DISPOSITION, dispositionType);
+                    AbstractField.CONTENT_DISPOSITION, dispositionType);
         } else {
             StringBuilder sb = new StringBuilder(dispositionType);
             for (Map.Entry<String, String> entry : parameters.entrySet()) {
@@ -244,7 +245,7 @@
      * @return the newly created <i>Date</i> field.
      */
     public static DateTimeField date(Date date) {
-        return date(Field.DATE, date, null);
+        return date(AbstractField.DATE, date, null);
     }
 
     /**
@@ -288,9 +289,9 @@
      *            <code>null</code> if no host name should be included.
      * @return the newly created <i>Message-ID</i> field.
      */
-    public static Field messageId(String hostname) {
+    public static AbstractField messageId(String hostname) {
         String fieldValue = MimeUtil.createUniqueMessageId(hostname);
-        return parse(UnstructuredField.class, Field.MESSAGE_ID, fieldValue);
+        return parse(UnstructuredField.class, AbstractField.MESSAGE_ID, fieldValue);
     }
 
     /**
@@ -302,11 +303,11 @@
      * @return the newly created <i>Subject</i> field.
      */
     public static UnstructuredField subject(String subject) {
-        int usedCharacters = Field.SUBJECT.length() + 2;
+        int usedCharacters = AbstractField.SUBJECT.length() + 2;
         String fieldValue = EncoderUtil.encodeIfNecessary(subject,
                 EncoderUtil.Usage.TEXT_TOKEN, usedCharacters);
 
-        return parse(UnstructuredField.class, Field.SUBJECT, fieldValue);
+        return parse(UnstructuredField.class, AbstractField.SUBJECT, fieldValue);
     }
 
     /**
@@ -317,7 +318,7 @@
      * @return the newly created <i>Sender</i> field.
      */
     public static MailboxField sender(Mailbox mailbox) {
-        return mailbox(Field.SENDER, mailbox);
+        return mailbox(AbstractField.SENDER, mailbox);
     }
 
     /**
@@ -328,7 +329,7 @@
      * @return the newly created <i>From</i> field.
      */
     public static MailboxListField from(Mailbox mailbox) {
-        return mailboxList(Field.FROM, Collections.singleton(mailbox));
+        return mailboxList(AbstractField.FROM, Collections.singleton(mailbox));
     }
 
     /**
@@ -339,7 +340,7 @@
      * @return the newly created <i>From</i> field.
      */
     public static MailboxListField from(Mailbox... mailboxes) {
-        return mailboxList(Field.FROM, Arrays.asList(mailboxes));
+        return mailboxList(AbstractField.FROM, Arrays.asList(mailboxes));
     }
 
     /**
@@ -350,7 +351,7 @@
      * @return the newly created <i>From</i> field.
      */
     public static MailboxListField from(Iterable<Mailbox> mailboxes) {
-        return mailboxList(Field.FROM, mailboxes);
+        return mailboxList(AbstractField.FROM, mailboxes);
     }
 
     /**
@@ -361,7 +362,7 @@
      * @return the newly created <i>To</i> field.
      */
     public static AddressListField to(Address address) {
-        return addressList(Field.TO, Collections.singleton(address));
+        return addressList(AbstractField.TO, Collections.singleton(address));
     }
 
     /**
@@ -372,7 +373,7 @@
      * @return the newly created <i>To</i> field.
      */
     public static AddressListField to(Address... addresses) {
-        return addressList(Field.TO, Arrays.asList(addresses));
+        return addressList(AbstractField.TO, Arrays.asList(addresses));
     }
 
     /**
@@ -383,7 +384,7 @@
      * @return the newly created <i>To</i> field.
      */
     public static AddressListField to(Iterable<Address> addresses) {
-        return addressList(Field.TO, addresses);
+        return addressList(AbstractField.TO, addresses);
     }
 
     /**
@@ -394,7 +395,7 @@
      * @return the newly created <i>Cc</i> field.
      */
     public static AddressListField cc(Address address) {
-        return addressList(Field.CC, Collections.singleton(address));
+        return addressList(AbstractField.CC, Collections.singleton(address));
     }
 
     /**
@@ -405,7 +406,7 @@
      * @return the newly created <i>Cc</i> field.
      */
     public static AddressListField cc(Address... addresses) {
-        return addressList(Field.CC, Arrays.asList(addresses));
+        return addressList(AbstractField.CC, Arrays.asList(addresses));
     }
 
     /**
@@ -416,7 +417,7 @@
      * @return the newly created <i>Cc</i> field.
      */
     public static AddressListField cc(Iterable<Address> addresses) {
-        return addressList(Field.CC, addresses);
+        return addressList(AbstractField.CC, addresses);
     }
 
     /**
@@ -427,7 +428,7 @@
      * @return the newly created <i>Bcc</i> field.
      */
     public static AddressListField bcc(Address address) {
-        return addressList(Field.BCC, Collections.singleton(address));
+        return addressList(AbstractField.BCC, Collections.singleton(address));
     }
 
     /**
@@ -438,7 +439,7 @@
      * @return the newly created <i>Bcc</i> field.
      */
     public static AddressListField bcc(Address... addresses) {
-        return addressList(Field.BCC, Arrays.asList(addresses));
+        return addressList(AbstractField.BCC, Arrays.asList(addresses));
     }
 
     /**
@@ -449,7 +450,7 @@
      * @return the newly created <i>Bcc</i> field.
      */
     public static AddressListField bcc(Iterable<Address> addresses) {
-        return addressList(Field.BCC, addresses);
+        return addressList(AbstractField.BCC, addresses);
     }
 
     /**
@@ -461,7 +462,7 @@
      * @return the newly created <i>Reply-To</i> field.
      */
     public static AddressListField replyTo(Address address) {
-        return addressList(Field.REPLY_TO, Collections.singleton(address));
+        return addressList(AbstractField.REPLY_TO, Collections.singleton(address));
     }
 
     /**
@@ -473,7 +474,7 @@
      * @return the newly created <i>Reply-To</i> field.
      */
     public static AddressListField replyTo(Address... addresses) {
-        return addressList(Field.REPLY_TO, Arrays.asList(addresses));
+        return addressList(AbstractField.REPLY_TO, Arrays.asList(addresses));
     }
 
     /**
@@ -485,7 +486,7 @@
      * @return the newly created <i>Reply-To</i> field.
      */
     public static AddressListField replyTo(Iterable<Address> addresses) {
-        return addressList(Field.REPLY_TO, addresses);
+        return addressList(AbstractField.REPLY_TO, addresses);
     }
 
     /**
@@ -565,12 +566,12 @@
         return EncoderUtil.isToken(dispositionType);
     }
 
-    private static <F extends Field> F parse(Class<F> fieldClass,
+    private static <F extends AbstractField> F parse(Class<F> fieldClass,
             String fieldName, String fieldBody) {
         try {
             String raw = MimeUtil.fold(fieldName + ": " + fieldBody, 0);
 
-            Field field = Field.parse(raw);
+            Field field = AbstractField.parse(raw);
             if (!fieldClass.isInstance(field)) {
                 throw new IllegalArgumentException("Incompatible field name: "
                         + fieldName);
Index: src/main/java/org/apache/james/mime4j/field/AbstractField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/AbstractField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/AbstractField.java	(working copy)
@@ -23,12 +23,13 @@
 import java.util.regex.Pattern;
 
 import org.apache.james.mime4j.MimeException;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.MimeUtil;
 
 /**
  * The base class of all field classes.
  */
-public abstract class Field {
+public abstract class AbstractField implements Field {
     public static final String SENDER = "Sender";
     public static final String FROM = "From";
     public static final String TO = "To";
@@ -63,7 +64,7 @@
     private final String body;
     private final String raw;
     
-    protected Field(final String name, final String body, final String raw) {
+    protected AbstractField(final String name, final String body, final String raw) {
         this.name = name;
         this.body = body;
         this.raw = raw;

Property changes on: src/main/java/org/apache/james/mime4j/field/AbstractField.java
___________________________________________________________________
Added: svn:mergeinfo

Index: src/main/java/org/apache/james/mime4j/field/UnstructuredField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/UnstructuredField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/UnstructuredField.java	(working copy)
@@ -24,7 +24,7 @@
 /**
  * Simple unstructured field such as <code>Subject</code>.
  */
-public class UnstructuredField extends Field {
+public class UnstructuredField extends AbstractField {
     private boolean parsed = false;
 
     private String value;
@@ -49,7 +49,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new UnstructuredField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/ContentTypeField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/ContentTypeField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/ContentTypeField.java	(working copy)
@@ -34,7 +34,7 @@
 /**
  * Represents a <code>Content-Type</code> field.
  */
-public class ContentTypeField extends Field {
+public class ContentTypeField extends AbstractField {
     private static Log log = LogFactory.getLog(ContentTypeField.class);
 
     /** The prefix of all <code>multipart</code> MIME types. */
@@ -249,7 +249,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new ContentTypeField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/Field.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/Field.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/Field.java	(working copy)
@@ -1,258 +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.field;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.james.mime4j.MimeException;
-import org.apache.james.mime4j.util.MimeUtil;
-
-/**
- * The base class of all field classes.
- */
-public abstract class Field {
-    public static final String SENDER = "Sender";
-    public static final String FROM = "From";
-    public static final String TO = "To";
-    public static final String CC = "Cc";
-    public static final String BCC = "Bcc";
-    public static final String REPLY_TO = "Reply-To";
-    public static final String RESENT_SENDER = "Resent-Sender";
-    public static final String RESENT_FROM = "Resent-From";
-    public static final String RESENT_TO = "Resent-To";
-    public static final String RESENT_CC = "Resent-Cc";
-    public static final String RESENT_BCC = "Resent-Bcc";
-
-    public static final String DATE = "Date";
-    public static final String RESENT_DATE = "Resent-Date";
-
-    public static final String SUBJECT = "Subject";
-
-    public static final String CONTENT_TYPE = "Content-Type";
-    public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
-    public static final String CONTENT_DISPOSITION = "Content-Disposition";
-
-    public static final String MESSAGE_ID = "Message-ID";
-
-    private static final String FIELD_NAME_PATTERN = 
-        "^([\\x21-\\x39\\x3b-\\x7e]+):";
-    private static final Pattern fieldNamePattern = 
-        Pattern.compile(FIELD_NAME_PATTERN);
-        
-    private static final DefaultFieldParser parser = new DefaultFieldParser();
-    
-    private final String name;
-    private final String body;
-    private final String raw;
-    
-    protected Field(final String name, final String body, final String raw) {
-        this.name = name;
-        this.body = body;
-        this.raw = raw;
-    }
-    
-    /**
-     * Parses the given string and returns an instance of the 
-     * <code>Field</code> class. The type of the class returned depends on
-     * the field name:
-     * <p>
-     * <table>
-     *   <tr><th>Class returned</th><th>Field names</th></tr>
-     *   <tr><td>{@link ContentTypeField}</td><td>Content-Type</td></tr>
-     *   <tr><td>{@link ContentTransferEncodingField}</td><td>Content-Transfer-Encoding</td></tr>
-     *   <tr><td>{@link ContentDispositionField}</td><td>Content-Disposition</td></tr>
-     *   <tr><td>{@link DateTimeField}</td><td>Date, Resent-Date</td></tr>
-     *   <tr><td>{@link MailboxField}</td><td>Sender, Resent-Sender</td></tr>
-     *   <tr><td>{@link MailboxListField}</td><td>From, Resent-From</td></tr>
-     *   <tr><td>{@link AddressListField}</td><td>To, Cc, Bcc, Reply-To, Resent-To, Resent-Cc, Resent-Bcc</td></tr>
-     *   <tr><td>{@link UnstructuredField}</td><td>Subject and others</td></tr>
-     * </table>
-     * 
-     * @param raw the string to parse.
-     * @return a <code>Field</code> instance.
-     * @throws MimeException if the raw string cannot be split into field name and body.
-     * @see #isValidField()
-     */
-    public static Field parse(final String raw) throws MimeException {
-        
-        /*
-         * Unfold the field.
-         */
-        final String unfolded = MimeUtil.unfold(raw);
-        
-        /*
-         * Split into name and value.
-         */
-        final Matcher fieldMatcher = fieldNamePattern.matcher(unfolded);
-        if (!fieldMatcher.find()) {
-            throw new MimeException("Invalid field in string");
-        }
-        final String name = fieldMatcher.group(1);
-        
-        String body = unfolded.substring(fieldMatcher.end());
-        if (body.length() > 0 && body.charAt(0) == ' ') {
-            body = body.substring(1);
-        }
-        
-        return parser.parse(name, body, raw);
-    }
-
-    /**
-     * Parses the given field name and field body strings and returns an
-     * instance of the <code>Field</code> class. The type of the class
-     * returned depends on the field name (see {@link #parse(String)}).
-     * <p>
-     * This method is convenient for creating or manipulating messages because
-     * contrary to {@link #parse(String)} it does not throw a
-     * {@link MimeException}.
-     * <p>
-     * Note that this method does not fold the header field; the specified field
-     * body should already have been folded into multiple lines prior to calling
-     * this method if folding is desired.
-     * 
-     * @param name
-     *            the field name.
-     * @param body
-     *            the field body (a.k.a value).
-     * @return a <code>Field</code> instance.
-     */
-    public static Field parse(String name, String body) {
-        if (body.length() > 0 && body.charAt(0) == ' ') {
-            body = body.substring(1);
-        }
-
-        String raw = name + ": " + body;
-
-        // Unfold body
-        body = MimeUtil.unfold(body);
-
-        return parser.parse(name, body, raw);
-    }
-
-    /**
-     * Gets the default parser used to parse fields.
-     * @return the default field parser
-     */
-    public static DefaultFieldParser getParser() {
-        return parser;
-    }
-    
-    /**
-     * Gets the name of the field (<code>Subject</code>, 
-     * <code>From</code>, etc).
-     * 
-     * @return the field name.
-     */
-    public String getName() {
-        return name;
-    }
-    
-    /**
-     * Gets the original raw field string.
-     * 
-     * @return the original raw field string.
-     */
-    public String getRaw() {
-        return raw;
-    }
-    
-    /**
-     * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field 
-     * body string.
-     * 
-     * @return the unfolded unparsed field body string.
-     */
-    public String getBody() {
-        return body;
-    }
-
-    /**
-     * Returns <code>true</code> if this field is valid, i.e. no errors were
-     * encountered while parsing the field value.
-     * 
-     * @return <code>true</code> if this field is valid, <code>false</code>
-     *         otherwise.
-     * @see #getParseException()
-     */
-    public boolean isValidField() {
-        return getParseException() == null;
-    }
-
-    /**
-     * Returns the exception that was thrown by the field parser while parsing
-     * the field value. The result is <code>null</code> if the field is valid
-     * and no errors were encountered.
-     * 
-     * @return the exception that was thrown by the field parser or
-     *         <code>null</code> if the field is valid.
-     */
-    public ParseException getParseException() {
-        return null;
-    }
-
-    /**
-     * Determines if this is a <code>Content-Type</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>Content-Type</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isContentType() {
-        return CONTENT_TYPE.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>Subject</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>Subject</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isSubject() {
-        return SUBJECT.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>From</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>From</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isFrom() {
-        return FROM.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>To</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>To</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isTo() {
-        return TO.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * @see #getRaw()
-     */
-    @Override
-    public String toString() {
-        return raw;
-    }
-}
Index: src/main/java/org/apache/james/mime4j/field/DelegatingFieldParser.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/DelegatingFieldParser.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/DelegatingFieldParser.java	(working copy)
@@ -22,6 +22,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.james.mime4j.parser.Field;
+
 public class DelegatingFieldParser implements FieldParser {
     
     private Map<String, FieldParser> parsers = new HashMap<String, FieldParser>();
Index: src/main/java/org/apache/james/mime4j/field/AddressListField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/AddressListField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/AddressListField.java	(working copy)
@@ -27,7 +27,7 @@
 /**
  * Address list field such as <code>To</code> or <code>Reply-To</code>.
  */
-public class AddressListField extends Field {
+public class AddressListField extends AbstractField {
     private static Log log = LogFactory.getLog(AddressListField.class);
 
     private boolean parsed = false;
@@ -70,7 +70,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new AddressListField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/ContentTransferEncodingField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/ContentTransferEncodingField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/ContentTransferEncodingField.java	(working copy)
@@ -24,7 +24,7 @@
 /**
  * Represents a <code>Content-Transfer-Encoding</code> field.
  */
-public class ContentTransferEncodingField extends Field {
+public class ContentTransferEncodingField extends AbstractField {
     private String encoding;
 
     ContentTransferEncodingField(String name, String body, String raw) {
@@ -56,7 +56,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new ContentTransferEncodingField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/field/MailboxListField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/field/MailboxListField.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/field/MailboxListField.java	(working copy)
@@ -28,7 +28,7 @@
 /**
  * Mailbox-list field such as <code>From</code> or <code>Resent-From</code>.
  */
-public class MailboxListField extends Field {
+public class MailboxListField extends AbstractField {
     private static Log log = LogFactory.getLog(MailboxListField.class);
 
     private boolean parsed = false;
@@ -71,7 +71,7 @@
     }
 
     static class Parser implements FieldParser {
-        public Field parse(final String name, final String body,
+        public AbstractField parse(final String name, final String body,
                 final String raw) {
             return new MailboxListField(name, body, raw);
         }
Index: src/main/java/org/apache/james/mime4j/message/Entity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Entity.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/Entity.java	(working copy)
@@ -27,7 +27,7 @@
 import org.apache.james.mime4j.field.ContentDispositionField;
 import org.apache.james.mime4j.field.ContentTransferEncodingField;
 import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.Fields;
 import org.apache.james.mime4j.util.MimeUtil;
 
@@ -264,10 +264,10 @@
      */
     public String getMimeType() {
         ContentTypeField child = 
-            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+            (ContentTypeField) getHeader().getField(AbstractField.CONTENT_TYPE);
         ContentTypeField parent = getParent() != null 
             ? (ContentTypeField) getParent().getHeader().
-                                                getField(Field.CONTENT_TYPE)
+                                                getField(AbstractField.CONTENT_TYPE)
             : null;
         
         return ContentTypeField.getMimeType(child, parent);
@@ -280,7 +280,7 @@
      */
     public String getCharset() {
         return ContentTypeField.getCharset( 
-            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
+            (ContentTypeField) getHeader().getField(AbstractField.CONTENT_TYPE));
     }
     
     /**
@@ -290,7 +290,7 @@
      */
     public String getContentTransferEncoding() {
         ContentTransferEncodingField f = (ContentTransferEncodingField) 
-                        getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
+                        getHeader().getField(AbstractField.CONTENT_TRANSFER_ENCODING);
         
         return ContentTransferEncodingField.getEncoding(f);
     }
@@ -315,7 +315,7 @@
      *         type has been set.
      */
     public String getDispositionType() {
-        ContentDispositionField field = obtainField(Field.CONTENT_DISPOSITION);
+        ContentDispositionField field = obtainField(AbstractField.CONTENT_DISPOSITION);
         if (field == null)
             return null;
 
@@ -415,7 +415,7 @@
      *         <code>null</code> if the filename has not been set.
      */
     public String getFilename() {
-        ContentDispositionField field = obtainField(Field.CONTENT_DISPOSITION);
+        ContentDispositionField field = obtainField(AbstractField.CONTENT_DISPOSITION);
         if (field == null)
             return null;
 
@@ -435,7 +435,7 @@
     public void setFilename(String filename) {
         Header header = obtainHeader();
         ContentDispositionField field = (ContentDispositionField) header
-                .getField(Field.CONTENT_DISPOSITION);
+                .getField(AbstractField.CONTENT_DISPOSITION);
         if (field == null) {
             if (filename != null) {
                 header.setField(Fields.contentDisposition(
@@ -478,7 +478,7 @@
      */
     public boolean isMultipart() {
         ContentTypeField f = 
-            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
+            (ContentTypeField) getHeader().getField(AbstractField.CONTENT_TYPE);
         return f != null && f.getBoundary() != null 
             && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
     }
@@ -521,7 +521,7 @@
      * @return the header field or <code>null</code> if this entity has no
      *         header or the header contains no such field.
      */
-    <F extends Field> F obtainField(String fieldName) {
+    <F extends AbstractField> F obtainField(String fieldName) {
         Header header = getHeader();
         if (header == null)
             return null;
Index: src/main/java/org/apache/james/mime4j/message/MessageWriter.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/MessageWriter.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/MessageWriter.java	(working copy)
@@ -32,7 +32,8 @@
 import org.apache.james.mime4j.MimeIOException;
 import org.apache.james.mime4j.codec.CodecUtil;
 import org.apache.james.mime4j.field.ContentTypeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.CharsetUtil;
 import org.apache.james.mime4j.util.MimeUtil;
 
@@ -224,7 +225,7 @@
     public void writeHeader(Header header, OutputStream out)
             throws IOException, MimeIOException {
         Writer writer = getWriter((ContentTypeField) header
-                .getField(Field.CONTENT_TYPE), out);
+                .getField(AbstractField.CONTENT_TYPE), out);
 
         try {
             for (Field field : header) {
@@ -271,7 +272,7 @@
                     "Missing header in parent entity");
 
         ContentTypeField contentType = (ContentTypeField) header
-                .getField(Field.CONTENT_TYPE);
+                .getField(AbstractField.CONTENT_TYPE);
         if (contentType == null)
             throw new IllegalArgumentException(
                     "Content-Type field not specified");
Index: src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/SimpleContentHandler.java	(working copy)
@@ -23,8 +23,8 @@
 import org.apache.james.mime4j.codec.Base64InputStream;
 import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
-import org.apache.james.mime4j.field.Field;
 import org.apache.james.mime4j.parser.AbstractContentHandler;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.MimeUtil;
 
 import java.io.InputStream;
@@ -72,11 +72,11 @@
     }
 
     /**
-     * @see org.apache.james.mime4j.parser.AbstractContentHandler#field(java.lang.String)
+     * @see org.apache.james.mime4j.parser.AbstractContentHandler#field(Field)
      */
     @Override
-    public final void field(String fieldData) throws MimeException {
-        currHeader.addField(Field.parse(fieldData));
+    public final void field(Field field) throws MimeException {
+        currHeader.addField(field);
     }
 
     /**
Index: src/main/java/org/apache/james/mime4j/message/Message.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Message.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/Message.java	(working copy)
@@ -32,7 +32,7 @@
 import org.apache.james.mime4j.MimeIOException;
 import org.apache.james.mime4j.field.AddressListField;
 import org.apache.james.mime4j.field.DateTimeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.Fields;
 import org.apache.james.mime4j.field.MailboxField;
 import org.apache.james.mime4j.field.MailboxListField;
@@ -110,8 +110,9 @@
      * @throws MimeIOException
      *             on MIME protocol violations.
      */
-    public Message(InputStream is, MimeEntityConfig config) throws IOException,
-            MimeIOException {
+    public Message(
+            InputStream is, 
+            MimeEntityConfig config) throws IOException, MimeIOException {
         this(is, config, DefaultStorageProvider.getInstance());
     }
 
@@ -131,7 +132,9 @@
      * @throws MimeIOException
      *             on MIME protocol violations.
      */
-    public Message(InputStream is, MimeEntityConfig config,
+    public Message(
+            InputStream is, 
+            MimeEntityConfig config,
             StorageProvider storageProvider) throws IOException,
             MimeIOException {
         try {
@@ -166,7 +169,7 @@
      * @return the identifier of this message.
      */
     public String getMessageId() {
-        Field field = obtainField(Field.MESSAGE_ID);
+        AbstractField field = obtainField(AbstractField.MESSAGE_ID);
         if (field == null)
             return null;
 
@@ -195,7 +198,7 @@
      * @return the subject of this message.
      */
     public String getSubject() {
-        UnstructuredField field = obtainField(Field.SUBJECT);
+        UnstructuredField field = obtainField(AbstractField.SUBJECT);
         if (field == null)
             return null;
 
@@ -216,7 +219,7 @@
         Header header = obtainHeader();
 
         if (subject == null) {
-            header.removeFields(Field.SUBJECT);
+            header.removeFields(AbstractField.SUBJECT);
         } else {
             header.setField(Fields.subject(subject));
         }
@@ -229,7 +232,7 @@
      * @return the date of this message.
      */
     public Date getDate() {
-        DateTimeField dateField = obtainField(Field.DATE);
+        DateTimeField dateField = obtainField(AbstractField.DATE);
         if (dateField == null)
             return null;
 
@@ -264,9 +267,9 @@
         Header header = obtainHeader();
 
         if (date == null) {
-            header.removeFields(Field.DATE);
+            header.removeFields(AbstractField.DATE);
         } else {
-            header.setField(Fields.date(Field.DATE, date, zone));
+            header.setField(Fields.date(AbstractField.DATE, date, zone));
         }
     }
 
@@ -278,7 +281,7 @@
      * @return the sender of this message.
      */
     public Mailbox getSender() {
-        return getMailbox(Field.SENDER);
+        return getMailbox(AbstractField.SENDER);
     }
 
     /**
@@ -290,7 +293,7 @@
      *            field.
      */
     public void setSender(Mailbox sender) {
-        setMailbox(Field.SENDER, sender);
+        setMailbox(AbstractField.SENDER, sender);
     }
 
     /**
@@ -301,7 +304,7 @@
      * @return value of the from field of this message.
      */
     public MailboxList getFrom() {
-        return getMailboxList(Field.FROM);
+        return getMailboxList(AbstractField.FROM);
     }
 
     /**
@@ -313,7 +316,7 @@
      *            field.
      */
     public void setFrom(Mailbox from) {
-        setMailboxList(Field.FROM, from);
+        setMailboxList(AbstractField.FROM, from);
     }
 
     /**
@@ -325,7 +328,7 @@
      *            remove the header field.
      */
     public void setFrom(Mailbox... from) {
-        setMailboxList(Field.FROM, from);
+        setMailboxList(AbstractField.FROM, from);
     }
 
     /**
@@ -337,7 +340,7 @@
      *            to remove the header field.
      */
     public void setFrom(Collection<Mailbox> from) {
-        setMailboxList(Field.FROM, from);
+        setMailboxList(AbstractField.FROM, from);
     }
 
     /**
@@ -348,7 +351,7 @@
      * @return value of the to field of this message.
      */
     public AddressList getTo() {
-        return getAddressList(Field.TO);
+        return getAddressList(AbstractField.TO);
     }
 
     /**
@@ -360,7 +363,7 @@
      *            field.
      */
     public void setTo(Address to) {
-        setAddressList(Field.TO, to);
+        setAddressList(AbstractField.TO, to);
     }
 
     /**
@@ -372,7 +375,7 @@
      *            remove the header field.
      */
     public void setTo(Address... to) {
-        setAddressList(Field.TO, to);
+        setAddressList(AbstractField.TO, to);
     }
 
     /**
@@ -384,7 +387,7 @@
      *            to remove the header field.
      */
     public void setTo(Collection<Address> to) {
-        setAddressList(Field.TO, to);
+        setAddressList(AbstractField.TO, to);
     }
 
     /**
@@ -395,7 +398,7 @@
      * @return value of the cc field of this message.
      */
     public AddressList getCc() {
-        return getAddressList(Field.CC);
+        return getAddressList(AbstractField.CC);
     }
 
     /**
@@ -407,7 +410,7 @@
      *            field.
      */
     public void setCc(Address cc) {
-        setAddressList(Field.CC, cc);
+        setAddressList(AbstractField.CC, cc);
     }
 
     /**
@@ -419,7 +422,7 @@
      *            remove the header field.
      */
     public void setCc(Address... cc) {
-        setAddressList(Field.CC, cc);
+        setAddressList(AbstractField.CC, cc);
     }
 
     /**
@@ -431,7 +434,7 @@
      *            to remove the header field.
      */
     public void setCc(Collection<Address> cc) {
-        setAddressList(Field.CC, cc);
+        setAddressList(AbstractField.CC, cc);
     }
 
     /**
@@ -442,7 +445,7 @@
      * @return value of the bcc field of this message.
      */
     public AddressList getBcc() {
-        return getAddressList(Field.BCC);
+        return getAddressList(AbstractField.BCC);
     }
 
     /**
@@ -454,7 +457,7 @@
      *            field.
      */
     public void setBcc(Address bcc) {
-        setAddressList(Field.BCC, bcc);
+        setAddressList(AbstractField.BCC, bcc);
     }
 
     /**
@@ -466,7 +469,7 @@
      *            remove the header field.
      */
     public void setBcc(Address... bcc) {
-        setAddressList(Field.BCC, bcc);
+        setAddressList(AbstractField.BCC, bcc);
     }
 
     /**
@@ -478,7 +481,7 @@
      *            to remove the header field.
      */
     public void setBcc(Collection<Address> bcc) {
-        setAddressList(Field.BCC, bcc);
+        setAddressList(AbstractField.BCC, bcc);
     }
 
     /**
@@ -489,7 +492,7 @@
      * @return value of the reply to field of this message.
      */
     public AddressList getReplyTo() {
-        return getAddressList(Field.REPLY_TO);
+        return getAddressList(AbstractField.REPLY_TO);
     }
 
     /**
@@ -501,7 +504,7 @@
      *            field.
      */
     public void setReplyTo(Address replyTo) {
-        setAddressList(Field.REPLY_TO, replyTo);
+        setAddressList(AbstractField.REPLY_TO, replyTo);
     }
 
     /**
@@ -513,7 +516,7 @@
      *            remove the header field.
      */
     public void setReplyTo(Address... replyTo) {
-        setAddressList(Field.REPLY_TO, replyTo);
+        setAddressList(AbstractField.REPLY_TO, replyTo);
     }
 
     /**
@@ -525,7 +528,7 @@
      *            to remove the header field.
      */
     public void setReplyTo(Collection<Address> replyTo) {
-        setAddressList(Field.REPLY_TO, replyTo);
+        setAddressList(AbstractField.REPLY_TO, replyTo);
     }
 
     private Mailbox getMailbox(String fieldName) {
Index: src/main/java/org/apache/james/mime4j/message/Header.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/Header.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/Header.java	(working copy)
@@ -30,8 +30,8 @@
 
 import org.apache.james.mime4j.MimeException;
 import org.apache.james.mime4j.MimeIOException;
-import org.apache.james.mime4j.field.Field;
 import org.apache.james.mime4j.parser.AbstractContentHandler;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.parser.MimeStreamParser;
 
 /**
@@ -81,8 +81,8 @@
                 parser.stop();
             }
             @Override
-            public void field(String fieldData) throws MimeException {
-                addField(Field.parse(fieldData));
+            public void field(Field field) throws MimeException {
+                addField(field);
             }
         });
         try {
Index: src/main/java/org/apache/james/mime4j/message/MessageBuilder.java
===================================================================
--- src/main/java/org/apache/james/mime4j/message/MessageBuilder.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/message/MessageBuilder.java	(working copy)
@@ -27,8 +27,9 @@
 import org.apache.james.mime4j.codec.Base64InputStream;
 import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
 import org.apache.james.mime4j.descriptor.BodyDescriptor;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.parser.ContentHandler;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.parser.MimeStreamParser;
 import org.apache.james.mime4j.storage.StorageProvider;
 import org.apache.james.mime4j.util.MimeUtil;
@@ -93,9 +94,10 @@
     /**
      * @see org.apache.james.mime4j.parser.ContentHandler#field(java.lang.String)
      */
-    public void field(String fieldData) throws MimeException {
+    public void field(Field field) throws MimeException {
         expect(Header.class);
-        ((Header) stack.peek()).addField(Field.parse(fieldData));
+        Field parsedfield = AbstractField.parse(field.getRaw()); 
+        ((Header) stack.peek()).addField(parsedfield);
     }
     
     /**
Index: src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/AbstractEntity.java	(working copy)
@@ -55,7 +55,7 @@
     private final CharArrayBuffer fieldbuf;
 
     private int lineCount;
-    private String field, fieldName, fieldValue;
+    private Field field;
     private boolean endOfHeader;
     private int headerCount;
 
@@ -195,7 +195,10 @@
             fieldbuf.setLength(len);
             
             boolean valid = true;
-            field = fieldbuf.toString();
+            
+            String fieldName = null;
+            String fieldValue = null;
+            
             int pos = fieldbuf.indexOf(':');
             if (pos <= 0) {
                 monitor(Event.INALID_HEADER);
@@ -212,7 +215,8 @@
                 fieldValue = fieldbuf.substring(pos + 1, fieldbuf.length());
             }
             if (valid) {
-                body.addField(fieldName, fieldValue);            
+                field = new RawField(fieldName, fieldValue, fieldbuf.toString());
+                body.addField(field);            
                 return true;
             }
         }
@@ -248,7 +252,7 @@
      * @throws IllegalStateException {@link #getState()} returns another
      *   value than {@link EntityStates#T_FIELD}.
      */
-    public String getField() {
+    public Field getField() {
         switch (getState()) {
         case EntityStates.T_FIELD:
             return field;
@@ -258,36 +262,6 @@
     }
 
     /**
-     * This method is valid, if {@link #getState()} returns {@link EntityStates#T_FIELD}.
-     * @return String with the fields name.
-     * @throws IllegalStateException {@link #getState()} returns another
-     *   value than {@link EntityStates#T_FIELD}.
-     */
-    public String getFieldName() {
-        switch (getState()) {
-        case EntityStates.T_FIELD:
-            return fieldName;
-        default:
-            throw new IllegalStateException("Invalid state :" + stateToString(state));
-        }
-    }
-
-    /**
-     * This method is valid, if {@link #getState()} returns {@link EntityStates#T_FIELD}.
-     * @return String with the fields value.
-     * @throws IllegalStateException {@link #getState()} returns another
-     *   value than {@link EntityStates#T_FIELD}.
-     */
-    public String getFieldValue() {
-        switch (getState()) {
-        case EntityStates.T_FIELD:
-            return fieldValue;
-        default:
-            throw new IllegalStateException("Invalid state :" + stateToString(state));
-        }
-    }
-
-    /**
      * Monitors the given event.
      * Subclasses may override to perform actions upon events.
      * Base implementation logs at warn.
Index: src/main/java/org/apache/james/mime4j/parser/EntityStateMachine.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/EntityStateMachine.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/EntityStateMachine.java	(working copy)
@@ -98,26 +98,6 @@
      * @throws IllegalStateException if a header field cannot be
      *  obtained at the current stage of the parsing process. 
      */
-    String getField() throws IllegalStateException;
+    Field getField() throws IllegalStateException;
     
-    /**
-     * Returns name of the current header field.
-     * 
-     * @return field name
-     * 
-     * @throws IllegalStateException if a header field cannot be
-     *  obtained at the current stage of the parsing process. 
-     */
-    String getFieldName() throws IllegalStateException;
-
-    /**
-     * Returns value of the current header field.
-     * 
-     * @return field value
-     * 
-     * @throws IllegalStateException if a header field cannot be
-     *  obtained at the current stage of the parsing process. 
-     */
-    String getFieldValue() throws IllegalStateException;
-    
 }
Index: src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/MimeTokenStream.java	(working copy)
@@ -339,31 +339,11 @@
      * @throws IllegalStateException {@link #getState()} returns another
      *   value than {@link #T_FIELD}.
      */
-    public String getField() {
+    public Field getField() {
         return currentStateMachine.getField();
     }
     
     /**
-     * This method is valid, if {@link #getState()} returns {@link #T_FIELD}.
-     * @return String with the fields name.
-     * @throws IllegalStateException {@link #getState()} returns another
-     *   value than {@link #T_FIELD}.
-     */
-    public String getFieldName() {
-        return currentStateMachine.getFieldName();
-    }
-
-    /**
-     * This method is valid, if {@link #getState()} returns {@link #T_FIELD}.
-     * @return String with the fields value.
-     * @throws IllegalStateException {@link #getState()} returns another
-     *   value than {@link #T_FIELD}.
-     */
-    public String getFieldValue() {
-        return currentStateMachine.getFieldValue();
-    }
-
-    /**
      * This method advances the token stream to the next token.
      * @throws IllegalStateException The method has been called, although
      *   {@link #getState()} was already {@link #T_END_OF_STREAM}.
Index: src/main/java/org/apache/james/mime4j/parser/ContentHandler.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/ContentHandler.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/ContentHandler.java	(working copy)
@@ -121,12 +121,10 @@
     /**
      * Called for each field of a header.
      * 
-     * @param fieldData the raw contents of the field 
-     *        (<code>Field-Name: field value</code>). The value will not be 
-     *        unfolded.
+     * @param field the MIME field.
      * @throws MimeException on processing errors
      */
-    void field(String fieldData) throws MimeException;
+    void field(Field field) throws MimeException;
 
     /**
      * Called when there are no more header fields in a message or body part.
Index: src/main/java/org/apache/james/mime4j/parser/Field.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/Field.java	(revision 0)
+++ src/main/java/org/apache/james/mime4j/parser/Field.java	(revision 0)
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.parser;
+
+/**
+ * The abstract MIME field.
+ */
+public interface Field {
+    
+    /**
+     * Gets the name of the field (<code>Subject</code>, 
+     * <code>From</code>, etc).
+     * 
+     * @return the field name.
+     */
+    String getName();
+
+    /**
+     * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field 
+     * body string.
+     * 
+     * @return the unfolded unparsed field body string.
+     */
+    String getBody();
+
+    /**
+     * Gets the original raw field string.
+     * 
+     * @return the original raw field string.
+     */
+    String getRaw();
+    
+}
Index: src/main/java/org/apache/james/mime4j/parser/MimeEntity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/MimeEntity.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/MimeEntity.java	(working copy)
@@ -94,7 +94,10 @@
             throw new IllegalStateException("Invalid state: " + stateToString(state));
         }
         skipHeader = true;
-        body.addField("Content-Type", contentType);
+        body.addField(new RawField(
+                "Content-Type", 
+                contentType,
+                "Content-Type: " +contentType));
     }
     
     @Override
Index: src/main/java/org/apache/james/mime4j/parser/RawEntity.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/RawEntity.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/RawEntity.java	(working copy)
@@ -71,7 +71,7 @@
     /**
      * This method has no effect and always returns <code>null</code>.
      */
-    public String getField() {
+    public Field getField() {
         return null;
     }
 
Index: src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/parser/AbstractContentHandler.java	(working copy)
@@ -77,9 +77,9 @@
     }
     
     /**
-     * @see org.apache.james.mime4j.parser.ContentHandler#field(java.lang.String)
+     * @see org.apache.james.mime4j.parser.ContentHandler#field(Field)
      */
-    public void field(String fieldData) throws MimeException {
+    public void field(Field field) throws MimeException {
     }
     
     /**
Index: src/main/java/org/apache/james/mime4j/parser/RawField.java
===================================================================
--- src/main/java/org/apache/james/mime4j/parser/RawField.java	(revision 0)
+++ src/main/java/org/apache/james/mime4j/parser/RawField.java	(revision 0)
@@ -0,0 +1,54 @@
+/****************************************************************
+ * 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.parser;
+
+/**
+ * The basic immutable MIME field.
+ */
+public class RawField implements Field {
+    
+    private final String name;
+    private final String body;
+    private final String raw;
+    
+    public RawField(String name, String body, String raw) {
+        super();
+        this.name = name;
+        this.body = body;
+        this.raw = raw;
+    }
+    
+    public String getName() {
+        return this.name;
+    }
+
+    public String getBody() {
+        return this.body;
+    }
+
+    public String getRaw() {
+        return this.raw;
+    }
+    
+    public String toString() {
+        return this.raw;
+    }
+    
+}

Property changes on: src/main/java/org/apache/james/mime4j/parser/RawField.java
___________________________________________________________________
Added: svn:mergeinfo

Index: src/main/java/org/apache/james/mime4j/util/StringArrayMap.java
===================================================================
--- src/main/java/org/apache/james/mime4j/util/StringArrayMap.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/util/StringArrayMap.java	(working copy)
@@ -29,7 +29,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.message.Header;
 import org.apache.james.mime4j.parser.ContentHandler;
 
@@ -40,7 +40,7 @@
  * <p>
  * Note that this class is not directly used anywhere in Mime4j.
  * Instead a user might choose to use it instead of {@link Header}
- * and {@link Field} in a custom {@link ContentHandler} implementation.
+ * and {@link AbstractField} in a custom {@link ContentHandler} implementation.
  * See also MIME4j-24.
  */
 public class StringArrayMap implements Serializable {
Index: src/main/java/org/apache/james/mime4j/descriptor/DefaultBodyDescriptor.java
===================================================================
--- src/main/java/org/apache/james/mime4j/descriptor/DefaultBodyDescriptor.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/descriptor/DefaultBodyDescriptor.java	(working copy)
@@ -24,6 +24,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.MimeUtil;
 
 /**
@@ -92,8 +93,10 @@
      * @param name the field name.
      * @param value the field value.
      */
-    public void addField(String name, String value) {
-        
+    public void addField(Field field) {
+        String name = field.getName();
+        String value = field.getBody();
+
         name = name.trim().toLowerCase();
         
         if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
Index: src/main/java/org/apache/james/mime4j/descriptor/MaximalBodyDescriptor.java
===================================================================
--- src/main/java/org/apache/james/mime4j/descriptor/MaximalBodyDescriptor.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/descriptor/MaximalBodyDescriptor.java	(working copy)
@@ -31,9 +31,9 @@
 import org.apache.james.mime4j.field.language.parser.ContentLanguageParser;
 import org.apache.james.mime4j.field.mimeversion.parser.MimeVersionParser;
 import org.apache.james.mime4j.field.structured.parser.StructuredFieldParser;
+import org.apache.james.mime4j.parser.Field;
 import org.apache.james.mime4j.util.MimeUtil;
 
-
 /**
  * Parses and stores values for standard MIME header values.
  * 
@@ -105,7 +105,9 @@
     }
     
     @Override
-    public void addField(String name, String value) {
+    public void addField(Field field) {
+        String name = field.getName();
+        String value = field.getBody();
         name = name.trim().toLowerCase();
         if (MimeUtil.MIME_HEADER_MIME_VERSION.equals(name) && !isMimeVersionSet) {
             parseMimeVersion(value);
@@ -122,7 +124,7 @@
         } else if (MimeUtil.MIME_HEADER_MD5.equals(name) && !isContentMD5Set) {
             parseMD5(value);
         } else {
-            super.addField(name, value);
+            super.addField(field);
         }
     }
     
Index: src/main/java/org/apache/james/mime4j/descriptor/MutableBodyDescriptor.java
===================================================================
--- src/main/java/org/apache/james/mime4j/descriptor/MutableBodyDescriptor.java	(revision 744866)
+++ src/main/java/org/apache/james/mime4j/descriptor/MutableBodyDescriptor.java	(working copy)
@@ -20,6 +20,8 @@
 
 package org.apache.james.mime4j.descriptor;
 
+import org.apache.james.mime4j.parser.Field;
+
 /**
  * Adds mutator.
  */
@@ -27,9 +29,8 @@
 
     /**
      * Adds a field to the body descriptor.
-     * @param pFieldName The fields name.
-     * @param pFieldValue The unparsed fields value.
+     * @param Field the MIME field.
      */
-    void addField(String pFieldName, String pFieldValue);
+    void addField(Field field);
 
 }
Index: examples/src/java/org/apache/james/mime4j/samples/tree/MessageTree.java
===================================================================
--- examples/src/java/org/apache/james/mime4j/samples/tree/MessageTree.java	(revision 744866)
+++ examples/src/java/org/apache/james/mime4j/samples/tree/MessageTree.java	(working copy)
@@ -43,7 +43,7 @@
 import org.apache.james.mime4j.field.AddressListField;
 import org.apache.james.mime4j.field.ContentTypeField;
 import org.apache.james.mime4j.field.DateTimeField;
-import org.apache.james.mime4j.field.Field;
+import org.apache.james.mime4j.field.AbstractField;
 import org.apache.james.mime4j.field.UnstructuredField;
 import org.apache.james.mime4j.field.address.Mailbox;
 import org.apache.james.mime4j.field.address.MailboxList;
@@ -55,6 +55,7 @@
 import org.apache.james.mime4j.message.Message;
 import org.apache.james.mime4j.message.Multipart;
 import org.apache.james.mime4j.message.TextBody;
+import org.apache.james.mime4j.parser.Field;
 
 /**
  * Displays a parsed Message in a window. The window will be divided into
@@ -321,8 +322,8 @@
                 textView.setText(date.toString());                
             } else if (o instanceof UnstructuredField){
                 textView.setText(((UnstructuredField) o).getValue());                
-            } else if (o instanceof Field){
-                textView.setText(((Field) o).getBody());                
+            } else if (o instanceof AbstractField){
+                textView.setText(((AbstractField) o).getBody());                
             } else {
                 /*
                  * The Object should be a Header or a String containing a 
