diff --git maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
index c09cfe9..9319ad6 100644
--- maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
+++ maildir/src/main/java/org/apache/james/mailbox/maildir/MaildirMessageName.java
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.james.mailbox.maildir;
 
+import javax.mail.Flags;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FilenameFilter;
@@ -30,8 +31,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.mail.Flags;
-
 public class MaildirMessageName {
 
     // the flags in Maildir message names
@@ -241,16 +240,29 @@ public class MaildirMessageName {
      * into its components hostname, size and flags and fills the respective variables.
      */
     private void splitHostNameAndMeta() {
-        int firstEnd = hostnameAndMeta.indexOf(',');
-        int secondEnd = hostnameAndMeta.indexOf(':', firstEnd + 1);
-        hostname = hostnameAndMeta.substring(0, firstEnd);
-        // there are flags
-        if (secondEnd != -1) {
-            sizeString = hostnameAndMeta.substring(firstEnd, secondEnd);
-            flagsString = hostnameAndMeta.substring(secondEnd, hostnameAndMeta.length());
+        String[] hostnamemetaFlags = hostnameAndMeta.split(":", 2);
+        if (hostnamemetaFlags.length >= 1) {
+          this.hostnameAndMeta = hostnamemetaFlags[0];
+          int firstEnd = hostnameAndMeta.indexOf(',');
+
+          // read size field if existent
+          if (firstEnd > 0) {
+            hostname = hostnameAndMeta.substring(0, firstEnd);
+            String attrStr = hostnameAndMeta.substring(firstEnd);
+            String[] fields = attrStr.split(",");
+            for (String field : fields) {
+              if (field.startsWith("S=")) {
+                  sizeString = "," + field;
+              }
+            }
+          } else {
+            sizeString = null;
+            hostname = this.hostnameAndMeta;
+          }
         }
-        else {
-            sizeString = hostnameAndMeta.substring(firstEnd, hostnameAndMeta.length());
+
+        if (hostnamemetaFlags.length >= 2) {
+            this.flagsString = ":" + hostnamemetaFlags[1];
         }
     }
     
@@ -276,7 +288,8 @@ public class MaildirMessageName {
             split();
             if (flagsString == null)
                 return null;
-            flags = decodeFlags(flagsString.substring(3)); // skip the ":2," part
+            if (flagsString.length() >= 3)
+                flags = decodeFlags(flagsString.substring(3)); // skip the ":2," part
         }
         return flags;
     }
@@ -290,6 +303,8 @@ public class MaildirMessageName {
             split();
             if (sizeString == null)
                 return null;
+            if (!sizeString.startsWith(",S="))
+                return null;
             size = Long.valueOf(sizeString.substring(3)); // skip the ",S=" part
         }
         return size;
diff --git maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index 77d2138..aafed31 100644
--- maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -18,18 +18,6 @@
  ****************************************************************/
 package org.apache.james.mailbox.maildir.mail.model;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.util.Date;
-import java.util.List;
-
-import javax.mail.Flags;
-import javax.mail.util.SharedFileInputStream;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.maildir.MaildirFolder;
 import org.apache.james.mailbox.maildir.MaildirMessageName;
@@ -47,6 +35,12 @@ import org.apache.james.mime4j.stream.MimeConfig;
 import org.apache.james.mime4j.stream.MimeTokenStream;
 import org.apache.james.mime4j.stream.RecursionMode;
 
+import javax.mail.Flags;
+import javax.mail.util.SharedFileInputStream;
+import java.io.*;
+import java.util.Date;
+import java.util.List;
+
 public class MaildirMessage extends AbstractMessage<Integer> {
 
     private MaildirMessageName messageName;
@@ -78,6 +72,8 @@ public class MaildirMessage extends AbstractMessage<Integer> {
         } else {
             // if the message resist in the new folder its RECENT
             if (file.getParentFile().getName().equals(MaildirFolder.NEW)) {
+                if (flags == null)
+                    flags = new Flags();
                 flags.add(Flags.Flag.RECENT);
             }
         }
@@ -378,7 +374,16 @@ public class MaildirMessage extends AbstractMessage<Integer> {
      */
     @Override
     public long getFullContentOctets() {
-        return messageName.getSize();
+        Long size = messageName.getSize();
+        if (size != null) {
+            return size;
+        } else {
+            try {
+                return messageName.getFile().length();
+            } catch (FileNotFoundException e) {
+                return -1;
+            }
+        }
     }
 
     /**
diff --git maildir/src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java maildir/src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
index 710c618..c79d452 100644
--- maildir/src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
+++ maildir/src/test/java/org/apache/james/mailbox/maildir/MailderMessageNameTest.java
@@ -1,8 +1,252 @@
+/****************************************************************
+ * 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.mailbox.maildir;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import javax.mail.Flags;
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.*;
+
 /**
- * @author <a href="mailto:eike.kettner@gmail.com">Eike Kettner</a>
  * @since 20.12.12 11:09
  */
+@RunWith(value = Parameterized.class)
 public class MailderMessageNameTest {
+
+    private String invalidName;
+    private String validName;
+    private Parts parts;
+
+    public MailderMessageNameTest(String invalidName, Parts parts) {
+        this.invalidName = invalidName;
+        this.validName = parts.fullName;
+        this.parts = parts;
+    }
+
+    @Parameterized.Parameters
+    public static List<Object[]> testData() {
+        List<Object[]> args = new ArrayList<Object[]>();
+        //no size, two flags
+        Parts parts = Parts.fullName("1328026049.19146_0.km1111:2,RS")
+                .timeSeconds(1328026049)
+                .baseName("1328026049.19146_0.km1111")
+                .flagAnswered().flagSeen();
+        args.add(valid(parts));
+
+        //size and flag
+        parts = Parts.fullName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111,S=13103:2,S")
+                .timeSeconds(1328613172)
+                .size(13103L)
+                .baseName("1328613172.M569643P1862V0000000000000902I00EE42CE_0.km1111")
+                .flagSeen();
+        args.add(valid(parts));
+
+        //size, no flags
+        parts = Parts.fullName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111,S=1344:2,")
+                .baseName("1340124194.M723289P3184V0000000000000902I006780E9_6.km1111")
+                .timeSeconds(1340124194)
+                .size(1344L);
+        args.add(valid(parts));
+
+        // three flags, no size
+        parts = Parts.fullName("1106685752.12132_0.km1111:2,FRS")
+                .baseName("1106685752.12132_0.km1111")
+                .timeSeconds(1106685752)
+                .flagFlagged().flagAnswered().flagSeen();
+        args.add(valid(parts));
+
+        //with dovecot attributes
+        parts = Parts.fullName("1035478339.27041_118.foo.org,S=1000,W=1030:2,S")
+                .baseName("1035478339.27041_118.foo.org")
+                .timeSeconds(1035478339)
+                .size(1000L)
+                .flagSeen();
+        args.add(valid(parts));
+
+        parts = parts.copy();
+        parts.fullName = "1035478339.27041_118.foo.org,W=1030,S=1000:2,S";
+        args.add(valid(parts));
+
+        // new mail, no info part at all. found in courier maildirs
+        parts = Parts.fullName("1355543030.15049_0.foo.org")
+                .baseName("1355543030.15049_0.foo.org")
+                .timeSeconds(1355543030)
+                .noFlags();
+        args.add(valid(parts));
+
+        //new mail, generated by james
+        parts = Parts.fullName("1356001301.e563087e30181513.foohost,S=629:2,")
+                .baseName("1356001301.e563087e30181513.foohost")
+                .timeSeconds(1356001301)
+                .size(629L);
+        args.add(valid(parts));
+
+        parts = Parts.fullName("1355675588.5c7e107958851103.foohost,S=654:2,S")
+                .timeSeconds(1355675588)
+                .baseName("1355675588.5c7e107958851103.foohost")
+                .size(654L)
+                .flagSeen();
+        args.add(valid(parts));
+
+        parts = Parts.fullName("1355675651.f3dd564265174501.foohost,S=661:2,")
+                .baseName("1355675651.f3dd564265174501.foohost")
+                .timeSeconds(1355675651)
+                .size(661L);
+        args.add(valid(parts));
+
+        return args;
+    }
+
+    private static Object[] valid(Parts parts) {
+        return invalidAndValid(null, parts);
+    }
+
+    private static Object[] invalid(String invalidName) {
+        return invalidAndValid(invalidName, null);
+    }
+
+    private static Object[] invalidAndValid(String invalidName, Parts validName) {
+        return new Object[]{invalidName, validName};
+    }
+
+    @Test
+    public void testParsing() throws Exception {
+        if (validName != null) {
+            try {
+                parseValidName(validName, parts);
+            } catch (Throwable e) {
+                throw new Exception("Valid name '" + validName + "' failed.", e);
+            }
+        }
+        if (invalidName != null) {
+            try {
+                parseInvalidName(invalidName);
+                fail("No error reported for invalid name: " + invalidName);
+            } catch (Exception e) {
+                //test successful
+            }
+        }
+    }
+
+    private void parseValidName(String name, Parts parts) throws Exception {
+        MaildirMessageName mn = new MaildirMessageName(null, name);
+        if (parts.time == null) {
+            assertNull("date", mn.getInternalDate());
+        } else {
+            assertEquals("date", mn.getInternalDate().getTime(), parts.time.longValue());
+        }
+        assertEquals("fullName", parts.fullName, mn.getFullName());
+        assertEquals("flags", parts.flags, mn.getFlags());
+        assertEquals("size", parts.size, mn.getSize());
+        assertEquals("baseName", parts.baseName, mn.getBaseName());
+    }
+
+    private void parseInvalidName(String name) throws Exception {
+    }
+
+    static class Parts {
+        public Long time;
+        public String fullName;
+        public String baseName;
+        public Long size;
+        public Flags flags = new Flags();
+
+        private Parts(String fullName) {
+            this.fullName = fullName;
+        }
+
+        public static Parts fullName(String fullName) {
+            return new Parts(fullName);
+        }
+
+        public Parts noFlags() {
+            this.flags = null;
+            return this;
+        }
+
+        public Parts flagSeen() {
+            this.flags.add(Flags.Flag.SEEN);
+            return this;
+        }
+
+        public Parts flagRecent() {
+            this.flags.add(Flags.Flag.RECENT);
+            return this;
+        }
+
+        public Parts flagAnswered() {
+            this.flags.add(Flags.Flag.ANSWERED);
+            return this;
+        }
+
+        public Parts flagFlagged() {
+            this.flags.add(Flags.Flag.FLAGGED);
+            return this;
+        }
+
+        public Parts flagDeleted() {
+            this.flags.add(Flags.Flag.DELETED);
+            return this;
+        }
+
+        public Parts flagDraft() {
+            this.flags.add(Flags.Flag.DRAFT);
+            return this;
+        }
+
+        public Parts baseName(String baseName) {
+            this.baseName = baseName;
+            return this;
+        }
+
+        public Parts size(Long size) {
+            this.size = size;
+            return this;
+        }
+
+        public Parts timeSeconds(Long time) {
+            if (time != null) {
+                this.time = time * 1000;
+            } else {
+                this.time = null;
+            }
+            return this;
+        }
+
+        public Parts timeMillis(Long time) {
+            this.time = time;
+            return this;
+        }
+
+        public Parts timeSeconds(Integer time) {
+            return timeSeconds(time != null ? time.longValue() : null);
+        }
+
+        public Parts copy() {
+            Parts p = Parts.fullName(fullName).baseName(baseName).size(size).timeMillis(time);
+            p.flags = (Flags) this.flags.clone();
+            return p;
+        }
+    }
 }
