diff --git a/Lib/mailbox.py b/Lib/mailbox.py
index c89c1a4..ac87a51 100755
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -1,13 +1,1884 @@
 #! /usr/bin/env python
 
-"""Classes to handle Unix style, MMDF style, and MH style mailboxes."""
+"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
 
-
-import rfc822
 import os
+import time
+import calendar
+import socket
+import errno
+import copy
+import email
+import email.Message
+import email.Generator
+import rfc822
+import StringIO
+try:
+    import fnctl
+except ImportError:
+    fcntl = None
 
-__all__ = ["UnixMailbox","MmdfMailbox","MHMailbox","Maildir","BabylMailbox",
-           "PortableUnixMailbox"]
+__all__ = [ 'Mailbox', 'Maildir', 'mbox', 'MH', 'Babyl', 'MMDF',
+            'Message', 'MaildirMessage', 'mboxMessage', 'MHMessage',
+            'BabylMessage', 'MMDFMessage', 'UnixMailbox',
+            'PortableUnixMailbox', 'MmdfMailbox', 'MHMailbox', 'BabylMailbox' ]
+
+
+class Mailbox:
+    """A group of messages in a particular place."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a Mailbox instance."""
+        self._path = os.path.abspath(os.path.expanduser(path))
+        self._factory = factory
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def __delitem__(self, key):
+        self.remove(key)
+
+    def discard(self, key):
+        """If the keyed message exists, remove it."""
+        try:
+            self.remove(key)
+        except KeyError:
+            pass
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get(self, key, default=None):
+        """Return the keyed message, or default if it doesn't exist."""
+        try:
+            return self.__getitem__(key)
+        except KeyError:
+            return default
+
+    def __getitem__(self, key):
+        """Return the keyed message; raise KeyError if it doesn't exist."""
+        if not self._factory:
+            return self.get_message(key)
+        else:
+            return self._factory(self.get_file(key))
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def keys(self):
+        """Return a list of keys."""
+        return list(self.iterkeys())
+
+    def itervalues(self):
+        """Return an iterator over all messages."""
+        for key in self.iterkeys():
+            try:
+                value = self[key]
+            except KeyError:
+                continue
+            yield value
+
+    def __iter__(self):
+        return self.itervalues()
+
+    def values(self):
+        """Return a list of messages. Memory intensive."""
+        return list(self.itervalues())
+
+    def iteritems(self):
+        """Return an iterator over (key, message) tuples."""
+        for key in self.iterkeys():
+            try:
+                value = self[key]
+            except KeyError:
+                continue
+            yield (key, value)
+
+    def items(self):
+        """Return a list of (key, message) tuples. Memory intensive."""
+        return list(self.iteritems())
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def __contains__(self, key):
+        return self.has_key(key)
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def clear(self):
+        """Delete all messages."""
+        for key in self.iterkeys():
+            self.discard(key)
+
+    def pop(self, key, default=None):
+        """Delete the keyed message and return it, or default."""
+        try:
+            result = self[key]
+        except KeyError:
+            return default
+        self.discard(key)
+        return result
+
+    def popitem(self):
+        """Delete an arbitrary (key, message) pair and return it."""
+        for key in self.iterkeys():
+            return (key, self.pop(key))     # This is only run once.
+        else:
+            raise KeyError('No messages in mailbox')
+
+    def update(self, arg=None):
+        """Change the messages that correspond to certain keys."""
+        if hasattr(arg, 'iteritems'):
+            source = arg.iteritems()
+        elif hasattr(arg, 'items'):
+            source = arg.items()
+        else:
+            source = arg
+        bad_key = False
+        for key, message in source:
+            try:
+                self[key] = message
+            except KeyError:
+                bad_key = True
+        if bad_key:
+            raise KeyError('No message with key(s)')
+
+    def flush(self):
+        """Write any pending changes to the disk."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def lock(self):
+        """Lock the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def close(self):
+        """Flush and close the mailbox."""
+        raise NotImplementedError('Method must be implemented by subclass')
+
+    def _dump_message(self, message, target, mangle_from_=False):
+        # Most files are opened in binary mode to allow predictable seeking.
+        # To get native line endings on disk, the user-friendly \n line endings
+        # used in strings and by email.Message are translated here.
+        """Dump message contents to target file."""
+        if isinstance(message, email.Message.Message):
+            buffer = StringIO.StringIO()
+            gen = email.Generator.Generator(buffer, mangle_from_, 0)
+            gen.flatten(message)
+            buffer.seek(0)
+            target.write(buffer.read().replace('\n', os.linesep))
+        elif isinstance(message, str):
+            if mangle_from_:
+                message = message.replace('\nFrom ', '\n>From ')
+            message = message.replace('\n', os.linesep)
+            target.write(message)
+        elif hasattr(message, 'read'):
+            while True:
+                line = message.readline()
+                if line == '':
+                    break
+                if mangle_from_ and line.startswith('From '):
+                    line = '>From ' + line[5:]
+                line = line.replace('\n', os.linesep)
+                target.write(line)
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+
+
+class Maildir(Mailbox):
+    """A qmail-style Maildir mailbox."""
+
+    colon = ':'
+
+    def __init__(self, dirname, factory=rfc822.Message, create=True):
+        """Initialize a Maildir instance."""
+        Mailbox.__init__(self, dirname, factory, create)
+        if not os.path.exists(self._path):
+            if create:
+                os.mkdir(self._path, 0700)
+                os.mkdir(os.path.join(self._path, 'tmp'), 0700)
+                os.mkdir(os.path.join(self._path, 'new'), 0700)
+                os.mkdir(os.path.join(self._path, 'cur'), 0700)
+            else:
+                raise NoSuchMailboxError(self._path)
+        self._toc = {}
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        tmp_file = self._create_tmp()
+        try:
+            self._dump_message(message, tmp_file)
+        finally:
+            tmp_file.close()
+        if isinstance(message, MaildirMessage):
+            subdir = message.get_subdir()
+            suffix = self.colon + message.get_info()
+            if suffix == self.colon:
+                suffix = ''
+        else:
+            subdir = 'new'
+            suffix = ''
+        uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
+        dest = os.path.join(self._path, subdir, uniq + suffix)
+        os.rename(tmp_file.name, dest)
+        if isinstance(message, MaildirMessage):
+            os.utime(dest, (os.path.getatime(dest), message.get_date()))
+        return uniq
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        os.remove(os.path.join(self._path, self._lookup(key)))
+
+    def discard(self, key):
+        """If the keyed message exists, remove it."""
+        # This overrides an inapplicable implementation in the superclass.
+        try:
+            self.remove(key)
+        except KeyError:
+            pass
+        except OSError, e:
+            if e.errno == errno.ENOENT:
+                pass
+            else:
+                raise 
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        old_subpath = self._lookup(key)
+        temp_key = self.add(message)
+        temp_subpath = self._lookup(temp_key)
+        if isinstance(message, MaildirMessage):
+            # temp's subdir and suffix were specified by message.
+            dominant_subpath = temp_subpath
+        else:
+            # temp's subdir and suffix were defaults from add().
+            dominant_subpath = old_subpath
+        subdir = os.path.dirname(dominant_subpath)
+        if self.colon in dominant_subpath:
+            suffix = self.colon + dominant_subpath.split(self.colon)[-1]
+        else:
+            suffix = ''
+        self.discard(key)
+        new_path = os.path.join(self._path, subdir, key + suffix)
+        os.rename(os.path.join(self._path, temp_subpath), new_path)
+        if isinstance(message, MaildirMessage):
+            os.utime(new_path, (os.path.getatime(new_path),
+                                message.get_date()))
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        subpath = self._lookup(key)
+        f = file(os.path.join(self._path, subpath), 'r')
+        try:
+            msg = MaildirMessage(f)
+        finally:
+            f.close()
+        subdir, name = os.path.split(subpath)
+        msg.set_subdir(subdir)
+        if self.colon in name:
+            msg.set_info(name.split(self.colon)[-1])
+        msg.set_date(os.path.getmtime(os.path.join(self._path, subpath)))
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        f = file(os.path.join(self._path, self._lookup(key)), 'r')
+        try:
+            return f.read()
+        finally:
+            f.close()
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        f = file(os.path.join(self._path, self._lookup(key)), 'rb')
+        return _ProxyFile(f)
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        self._refresh()
+        for key in self._toc:
+            try:
+                self._lookup(key)
+            except KeyError:
+                continue
+            yield key
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        self._refresh()
+        return key in self._toc
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        self._refresh()
+        return len(self._toc)
+
+    def flush(self):
+        """Write any pending changes to disk."""
+        return  # Maildir changes are always written immediately.
+
+    def lock(self):
+        """Lock the mailbox."""
+        return
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        return
+
+    def list_folders(self):
+        """Return a list of folder names."""
+        result = []
+        for entry in os.listdir(self._path):
+            if len(entry) > 1 and entry[0] == '.' and \
+               os.path.isdir(os.path.join(self._path, entry)):
+                result.append(entry[1:])
+        return result
+
+    def get_folder(self, folder):
+        """Return a Maildir instance for the named folder."""
+        return Maildir(os.path.join(self._path, '.' + folder), create=False)
+
+    def add_folder(self, folder):
+        """Create a folder and return a Maildir instance representing it."""
+        path = os.path.join(self._path, '.' + folder)
+        result = Maildir(path)
+        maildirfolder_path = os.path.join(path, 'maildirfolder')
+        if not os.path.exists(maildirfolder_path):
+            os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY))
+        return result
+
+    def remove_folder(self, folder):
+        """Delete the named folder, which must be empty."""
+        path = os.path.join(self._path, '.' + folder)
+        for entry in os.listdir(os.path.join(path, 'new')) + \
+                     os.listdir(os.path.join(path, 'cur')):
+            if len(entry) < 1 or entry[0] != '.':
+                raise NotEmptyError('Folder contains message(s): %s' % folder)
+        for entry in os.listdir(path):
+            if entry != 'new' and entry != 'cur' and entry != 'tmp' and \
+               os.path.isdir(os.path.join(path, entry)):
+                raise NotEmptyError("Folder contains subdirectory '%s': %s" %
+                                    (folder, entry))
+        for root, dirs, files in os.walk(path, topdown=False):
+            for entry in files:
+                os.remove(os.path.join(root, entry))
+            for entry in dirs:
+                os.rmdir(os.path.join(root, entry))
+        os.rmdir(path)
+
+    def clean(self):
+        """Delete old files in "tmp"."""
+        now = time.time()
+        for entry in os.listdir(os.path.join(self._path, 'tmp')):
+            path = os.path.join(self._path, 'tmp', entry)
+            if now - os.path.getatime(path) > 129600:   # 60 * 60 * 36
+                os.remove(path)
+
+    _count = 1  # This is used to generate unique file names.
+
+    def _create_tmp(self):
+        """Create a file in the tmp subdirectory and open and return it."""
+        now = time.time()
+        hostname = socket.gethostname()
+        if '/' in hostname:
+            hostname = hostname.replace('/', r'\057')
+        if ':' in hostname:
+            hostname = hostname.replace(':', r'\072')
+        uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(),
+                                    Maildir._count, hostname)
+        path = os.path.join(self._path, 'tmp', uniq)
+        try:
+            os.stat(path)
+        except OSError, e:
+            if e.errno == errno.ENOENT:
+                Maildir._count += 1
+                return file(path, 'wb+')
+            else:
+                raise
+        else:
+            raise ExternalClashError('Name clash prevented file creation: %s' %
+                                     path)
+
+    def _refresh(self):
+        """Update table of contents mapping."""
+        self._toc = {}
+        for subdir in ('new', 'cur'):
+            for entry in os.listdir(os.path.join(self._path, subdir)):
+                uniq = entry.split(self.colon)[0]
+                self._toc[uniq] = os.path.join(subdir, entry)
+
+    def _lookup(self, key):
+        """Use TOC to return subpath for given key, or raise a KeyError."""
+        try:
+            if os.path.exists(os.path.join(self._path, self._toc[key])):
+                return self._toc[key]
+        except KeyError:
+            pass
+        self._refresh()
+        try:
+            return self._toc[key]
+        except KeyError:
+            raise KeyError('No message with key: %s' % key)
+
+    # This method is for backward compatibility only.
+    def next(self):
+        """Return the next message in a one-time iteration."""
+        if not hasattr(self, '_onetime_keys'):
+            self._onetime_keys = self.iterkeys()
+        while True:
+            try:
+                return self[self._onetime_keys.next()]
+            except StopIteration:
+                return None
+            except KeyError:
+                continue
+
+
+class _singlefileMailbox(Mailbox):
+    """A single-file mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a single-file mailbox."""
+        Mailbox.__init__(self, path, factory, create)
+        try:
+            f = file(self._path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                if create:
+                    f = file(self._path, 'wb+')
+                else:
+                    raise NoSuchMailboxError(self._path)
+            elif e.errno == errno.EACCES:
+                f = file(self._path, 'rb')
+            else:
+                raise
+        self._file = f
+        self._toc = None
+        self._next_key = 0
+        self._pending = False   # No changes require rewriting the file.
+        self._locked = False
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        self._lookup()
+        self._toc[self._next_key] = self._append_message(message)
+        self._next_key += 1
+        self._pending = True
+        return self._next_key - 1
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        self._lookup(key)
+        del self._toc[key]
+        self._pending = True
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        self._lookup(key)
+        self._toc[key] = self._append_message(message)
+        self._pending = True
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        self._lookup()
+        for key in self._toc.keys():
+            yield key
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        self._lookup()
+        return key in self._toc
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        self._lookup()
+        return len(self._toc)
+
+    def lock(self):
+        """Lock the mailbox."""
+        if not self._locked:
+            _lock_file(self._file)
+            self._locked = True
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        if self._locked:
+            _unlock_file(self._file)
+            self._locked = False
+
+    def flush(self):
+        """Write any pending changes to disk."""
+        if not self._pending:
+            return
+        self._lookup()
+        new_file = _create_temporary(self._path)
+        try:
+            new_toc = {}
+            self._pre_mailbox_hook(new_file)
+            for key in sorted(self._toc.keys()):
+                start, stop = self._toc[key]
+                self._file.seek(start)
+                self._pre_message_hook(new_file)
+                new_start = new_file.tell()
+                while True:
+                    buffer = self._file.read(min(4096,
+                                                 stop - self._file.tell()))
+                    if buffer == '':
+                        break
+                    new_file.write(buffer)
+                new_toc[key] = (new_start, new_file.tell())
+                self._post_message_hook(new_file)
+        except:
+            new_file.close()
+            os.remove(new_file.name)
+            raise
+        new_file.close()
+        self._file.close()
+        try:
+            os.rename(new_file.name, self._path)
+        except OSError, e:
+            if e.errno == errno.EEXIST:
+                os.remove(self._path)
+                os.rename(new_file.name, self._path)
+            else:
+                raise
+        self._file = file(self._path, 'rb+')
+        self._toc = new_toc
+        self._pending = False
+        if self._locked:
+            _lock_file(new_file, dotlock=False)
+
+    def _pre_mailbox_hook(self, f):
+        """Called before writing the mailbox to file f."""
+        return
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        return
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        self.flush()
+        if self._locked:
+            self.unlock()
+        self._file.close()
+
+    def _lookup(self, key=None):
+        """Return (start, stop) or raise KeyError."""
+        if self._toc is None:
+            self._generate_toc()
+        if key is not None:
+            try:
+                return self._toc[key]
+            except KeyError:
+                raise KeyError('No message with key: %s' % key)
+
+    def _append_message(self, message):
+        """Append message to mailbox and return (start, stop) offsets."""
+        self._file.seek(0, 2)
+        self._pre_message_hook(self._file)
+        offsets = self._install_message(message)
+        self._post_message_hook(self._file)
+        self._file.flush()
+        return offsets
+
+
+
+class _mboxMMDF(_singlefileMailbox):
+    """An mbox or MMDF mailbox."""
+
+    _mangle_from_ = True
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        from_line = self._file.readline().replace(os.linesep, '')
+        string = self._file.read(stop - self._file.tell())
+        msg = self._message_factory(string.replace(os.linesep, '\n'))
+        msg.set_from(from_line[5:])
+        return msg
+
+    def get_string(self, key, from_=False):
+        """Return a string representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        if not from_:
+            self._file.readline()
+        string = self._file.read(stop - self._file.tell())
+        return string.replace(os.linesep, '\n')
+
+    def get_file(self, key, from_=False):
+        """Return a file-like representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        if not from_:
+            self._file.readline()
+        return _PartialFile(self._file, self._file.tell(), stop)
+
+    def _install_message(self, message):
+        """Format a message and blindly write to self._file."""
+        from_line = None
+        if isinstance(message, str) and message.startswith('From '):
+            newline = message.find('\n')
+            if newline != -1:
+                from_line = message[:newline]
+                message = message[newline + 1:]
+            else:
+                from_line = message
+                message = ''
+        elif isinstance(message, _mboxMMDFMessage):
+            from_line = 'From ' + message.get_from()
+        elif isinstance(message, email.Message.Message):
+            from_line = message.get_unixfrom()  # May be None.
+        if from_line is None:
+            from_line = 'From MAILER-DAEMON %s' % time.asctime(time.gmtime())
+        start = self._file.tell()
+        self._file.write(from_line + os.linesep)
+        self._dump_message(message, self._file, self._mangle_from_)
+        stop = self._file.tell()
+        return (start, stop)
+
+
+class mbox(_mboxMMDF):
+    """A classic mbox mailbox."""
+
+    _mangle_from_ = True
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an mbox mailbox."""
+        self._message_factory = mboxMessage
+        _mboxMMDF.__init__(self, path, factory, create)
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        if f.tell() != 0:
+            f.write(os.linesep)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        while True:
+            line_pos = self._file.tell()
+            line = self._file.readline()
+            if line.startswith('From '):
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+                starts.append(line_pos)
+            elif line == '':
+                stops.append(line_pos)
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._next_key = len(self._toc)
+
+
+class MMDF(_mboxMMDF):
+    """An MMDF mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an MMDF mailbox."""
+        self._message_factory = MMDFMessage
+        _mboxMMDF.__init__(self, path, factory, create)
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        f.write('\001\001\001\001' + os.linesep)
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        f.write(os.linesep + '\001\001\001\001' + os.linesep)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        next_pos = 0
+        while True:
+            line_pos = next_pos
+            line = self._file.readline()
+            next_pos = self._file.tell()
+            if line.startswith('\001\001\001\001' + os.linesep):
+                starts.append(next_pos)
+                while True:
+                    line_pos = next_pos
+                    line = self._file.readline()
+                    next_pos = self._file.tell()
+                    if line == '\001\001\001\001' + os.linesep:
+                        stops.append(line_pos - len(os.linesep))
+                        break
+                    elif line == '':
+                        stops.append(line_pos)
+                        break
+            elif line == '':
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._next_key = len(self._toc)
+
+
+class MH(Mailbox):
+    """An MH mailbox."""
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize an MH instance."""
+        Mailbox.__init__(self, path, factory, create)
+        if not os.path.exists(self._path):
+            if create:
+                os.mkdir(self._path, 0700)
+                os.close(os.open(os.path.join(self._path, '.mh_sequences'),
+                                 os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0600))
+            else:
+                raise NoSuchMailboxError(self._path)
+        self._locked = False
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        keys = self.keys()
+        if len(keys) == 0:
+            new_key = 1
+        else:
+            new_key = max(keys) + 1
+        new_path = os.path.join(self._path, str(new_key))
+        f = _create_carefully(new_path)
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                self._dump_message(message, f)
+                if isinstance(message, MHMessage):
+                    self._dump_sequences(message, new_key)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+        return new_key
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        path = os.path.join(self._path, str(key))
+        try:
+            f = file(path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                f.close()
+                os.remove(os.path.join(self._path, str(key)))
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        path = os.path.join(self._path, str(key))
+        try:
+            f = file(path, 'rb+')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                os.close(os.open(path, os.O_WRONLY | os.O_TRUNC))
+                self._dump_message(message, f)
+                if isinstance(message, MHMessage):
+                    self._dump_sequences(message, key)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        try:
+            if self._locked:
+                f = file(os.path.join(self._path, str(key)), 'r+')
+            else:
+                f = file(os.path.join(self._path, str(key)), 'r')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                msg = MHMessage(f)
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+        for name, key_list in self.get_sequences():
+            if key in key_list:
+                msg.add_sequence(name)
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        try:
+            if self._locked:
+                f = file(os.path.join(self._path, str(key)), 'r+')
+            else:
+                f = file(os.path.join(self._path, str(key)), 'r')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        try:
+            if self._locked:
+                _lock_file(f)
+            try:
+                return f.read()
+            finally:
+                if self._locked:
+                    _unlock_file(f)
+        finally:
+            f.close()
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        try:
+            f = file(os.path.join(self._path, str(key)), 'rb')
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                raise KeyError('No message with key: %s' % key)
+            else:
+                raise
+        return _ProxyFile(f)
+
+    def iterkeys(self):
+        """Return an iterator over keys."""
+        return iter(sorted(int(entry) for entry in os.listdir(self._path)
+                                      if entry.isdigit()))
+
+    def has_key(self, key):
+        """Return True if the keyed message exists, False otherwise."""
+        return os.path.exists(os.path.join(self._path, str(key)))
+
+    def __len__(self):
+        """Return a count of messages in the mailbox."""
+        return len(list(self.iterkeys()))
+
+    def lock(self):
+        """Lock the mailbox."""
+        if not self._locked:
+            self._file = file(os.path.join(self._path, '.mh_sequences'), 'rb+')
+            _lock_file(self._file)
+            self._locked = True
+
+    def unlock(self):
+        """Unlock the mailbox if it is locked."""
+        if self._locked:
+            _unlock_file(self._file)
+            self._file.close()
+            del self._file
+            self._locked = False
+
+    def flush(self):
+        """Write any pending changes to the disk."""
+        return
+
+    def close(self):
+        """Flush and close the mailbox."""
+        if self._locked:
+            self.unlock()
+
+    def list_folders(self):
+        """Return a list of folder names."""
+        result = []
+        for entry in os.listdir(self._path):
+            if os.path.isdir(os.path.join(self._path, entry)):
+                result.append(entry)
+        return result
+
+    def get_folder(self, folder):
+        """Return an MH instance for the named folder."""
+        return MH(os.path.join(self._path, folder), create=False)
+
+    def add_folder(self, folder):
+        """Create a folder and return an MH instance representing it."""
+        return MH(os.path.join(self._path, folder))
+
+    def remove_folder(self, folder):
+        """Delete the named folder, which must be empty."""
+        path = os.path.join(self._path, folder)
+        entries = os.listdir(path)
+        if entries == ['.mh_sequences']:
+            os.remove(os.path.join(path, '.mh_sequences'))
+        elif entries == []:
+            pass
+        else:
+            raise NotEmptyError('Folder not empty: %s' % self._path)
+        os.rmdir(path)
+
+    def get_sequences(self):
+        """Return a name-to-key-list dictionary to define each sequence."""
+        results = {}
+        f = file(os.path.join(self._path, '.mh_sequences'), 'r')
+        try:
+            all_keys = set(self.keys())
+            for line in f:
+                try:
+                    name, contents = line.split(':')
+                    keys = set()
+                    for spec in contents.split():
+                        if spec.isdigit():
+                            keys.add(int(spec))
+                        else:
+                            start, stop = (int(x) for x in spec.split('-'))
+                            keys.update(range(start, stop + 1))
+                    results[name] = [key for key in sorted(keys) \
+                                         if key in all_keys]
+                    if len(results[name]) == 0:
+                        del results[name]
+                except ValueError:
+                    raise FormatError('Invalid sequence specification: %s' %
+                                      line.rstrip())
+        finally:
+            f.close()
+        return results
+
+    def set_sequences(self, sequences):
+        """Set sequences using the given name-to-key-list dictionary."""
+        f = file(os.path.join(self._path, '.mh_sequences'), 'r+')
+        try:
+            os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC))
+            for name, keys in sequences.iteritems():
+                if len(keys) == 0:
+                    continue
+                f.write('%s:' % name)
+                prev = None
+                completing = False
+                for key in sorted(set(keys)):
+                    if key - 1 == prev:
+                        if not completing:
+                            completing = True
+                            f.write('-')
+                    elif completing:
+                        completing = False
+                        f.write('%s %s' % (prev, key))
+                    else:
+                        f.write(' %s' % key)
+                    prev = key
+                if completing:
+                    f.write(str(prev) + '\n')
+                else:
+                    f.write('\n')
+        finally:
+            f.close()
+
+    def pack(self):
+        """Re-name messages to eliminate numbering gaps. Invalidates keys."""
+        sequences = self.get_sequences()
+        prev = 0
+        changes = []
+        for key in self.iterkeys():
+            if key - 1 != prev:
+                changes.append((key, prev + 1))
+                f = file(os.path.join(self._path, str(key)), 'r+')
+                try:
+                    if self._locked:
+                        _lock_file(f)
+                    try:
+                        if hasattr(os, 'link'):
+                            os.link(os.path.join(self._path, str(key)),
+                                    os.path.join(self._path, str(prev + 1)))
+                            os.unlink(os.path.join(self._path, str(key)))
+                        else:
+                            f.close()
+                            os.rename(os.path.join(self._path, str(key)),
+                                      os.path.join(self._path, str(prev + 1)))
+                    finally:
+                        if self._locked:
+                            _unlock_file(f)
+                finally:
+                    f.close()
+            prev += 1
+        self._next_key = prev + 1
+        if len(changes) == 0:
+            return
+        for name, key_list in sequences.items():
+            for old, new in changes:
+                if old in key_list:
+                    key_list[key_list.index(old)] = new
+        self.set_sequences(sequences)
+
+    def _dump_sequences(self, message, key):
+        """Inspect a new MHMessage and update sequences appropriately."""
+        pending_sequences = message.get_sequences()
+        all_sequences = self.get_sequences()
+        for name, key_list in all_sequences.iteritems():
+            if name in pending_sequences:
+                key_list.append(key)
+            elif key in key_list:
+                del key_list[key_list.index(key)]
+        for sequence in pending_sequences:
+            if sequence not in all_sequences:
+                all_sequences[sequence] = [key]
+        self.set_sequences(all_sequences)
+
+
+class Babyl(_singlefileMailbox):
+    """An Rmail-style Babyl mailbox."""
+
+    _special_labels = frozenset(('unseen', 'deleted', 'filed', 'answered',
+                                 'forwarded', 'edited', 'resent'))
+
+    def __init__(self, path, factory=None, create=True):
+        """Initialize a Babyl mailbox."""
+        _singlefileMailbox.__init__(self, path, factory, create)
+        self._labels = {}
+
+    def add(self, message):
+        """Add message and return assigned key."""
+        key = _singlefileMailbox.add(self, message)
+        if isinstance(message, BabylMessage):
+            self._labels[key] = message.get_labels()
+        return key
+
+    def remove(self, key):
+        """Remove the keyed message; raise KeyError if it doesn't exist."""
+        _singlefileMailbox.remove(self, key)
+        if key in self._labels:
+            del self._labels[key]
+
+    def __setitem__(self, key, message):
+        """Replace the keyed message; raise KeyError if it doesn't exist."""
+        _singlefileMailbox.__setitem__(self, key, message)
+        if isinstance(message, BabylMessage):
+            self._labels[key] = message.get_labels()
+
+    def get_message(self, key):
+        """Return a Message representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        self._file.readline()   # Skip '1,' line specifying labels.
+        original_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == '*** EOOH ***' + os.linesep or line == '':
+                break
+            original_headers.write(line.replace(os.linesep, '\n'))
+        visible_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == os.linesep or line == '':
+                break
+            visible_headers.write(line.replace(os.linesep, '\n'))
+        body = self._file.read(stop - self._file.tell()).replace(os.linesep,
+                                                                 '\n')
+        msg = BabylMessage(original_headers.getvalue() + body)
+        msg.set_visible(visible_headers.getvalue())
+        if key in self._labels:
+            msg.set_labels(self._labels[key])
+        return msg
+
+    def get_string(self, key):
+        """Return a string representation or raise a KeyError."""
+        start, stop = self._lookup(key)
+        self._file.seek(start)
+        self._file.readline()   # Skip '1,' line specifying labels.
+        original_headers = StringIO.StringIO()
+        while True:
+            line = self._file.readline()
+            if line == '*** EOOH ***' + os.linesep or line == '':
+                break
+            original_headers.write(line.replace(os.linesep, '\n'))
+        while True:
+            line = self._file.readline()
+            if line == os.linesep or line == '':
+                break
+        return original_headers.getvalue() + \
+               self._file.read(stop - self._file.tell()).replace(os.linesep,
+                                                                 '\n')
+
+    def get_file(self, key):
+        """Return a file-like representation or raise a KeyError."""
+        return StringIO.StringIO(self.get_string(key).replace('\n',
+                                                              os.linesep))
+
+    def get_labels(self):
+        """Return a list of user-defined labels in the mailbox."""
+        self._lookup()
+        labels = set()
+        for label_list in self._labels.values():
+            labels.update(label_list)
+        labels.difference_update(self._special_labels)
+        return list(labels)
+
+    def _generate_toc(self):
+        """Generate key-to-(start, stop) table of contents."""
+        starts, stops = [], []
+        self._file.seek(0)
+        next_pos = 0
+        label_lists = []
+        while True:
+            line_pos = next_pos
+            line = self._file.readline()
+            next_pos = self._file.tell()
+            if line == '\037\014' + os.linesep:
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+                starts.append(next_pos)
+                labels = [label.strip() for label
+                                        in self._file.readline()[1:].split(',')
+                                        if label.strip() != '']
+                label_lists.append(labels)
+            elif line == '\037' or line == '\037' + os.linesep:
+                if len(stops) < len(starts):
+                    stops.append(line_pos - len(os.linesep))
+            elif line == '':
+                stops.append(line_pos - len(os.linesep))
+                break
+        self._toc = dict(enumerate(zip(starts, stops)))
+        self._labels = dict(enumerate(label_lists))
+        self._next_key = len(self._toc)
+
+    def _pre_mailbox_hook(self, f):
+        """Called before writing the mailbox to file f."""
+        f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' %
+                (os.linesep, os.linesep, ','.join(self.get_labels()),
+                 os.linesep))
+
+    def _pre_message_hook(self, f):
+        """Called before writing each message to file f."""
+        f.write('\014' + os.linesep)
+
+    def _post_message_hook(self, f):
+        """Called after writing each message to file f."""
+        f.write(os.linesep + '\037')
+
+    def _install_message(self, message):
+        """Write message contents and return (start, stop)."""
+        start = self._file.tell()
+        if isinstance(message, BabylMessage):
+            special_labels = []
+            labels = []
+            for label in message.get_labels():
+                if label in self._special_labels:
+                    special_labels.append(label)
+                else:
+                    labels.append(label)
+            self._file.write('1')
+            for label in special_labels:
+                self._file.write(', ' + label)
+            self._file.write(',,')
+            for label in labels:
+                self._file.write(' ' + label + ',')
+            self._file.write(os.linesep)
+        else:
+            self._file.write('1,,' + os.linesep)
+        if isinstance(message, email.Message.Message):
+            orig_buffer = StringIO.StringIO()
+            orig_generator = email.Generator.Generator(orig_buffer, False, 0)
+            orig_generator.flatten(message)
+            orig_buffer.seek(0)
+            while True:
+                line = orig_buffer.readline()
+                self._file.write(line.replace('\n', os.linesep))
+                if line == '\n' or line == '':
+                    break
+            self._file.write('*** EOOH ***' + os.linesep)
+            if isinstance(message, BabylMessage):
+                vis_buffer = StringIO.StringIO()
+                vis_generator = email.Generator.Generator(vis_buffer, False, 0)
+                vis_generator.flatten(message.get_visible())
+                while True:
+                    line = vis_buffer.readline()
+                    self._file.write(line.replace('\n', os.linesep))
+                    if line == '\n' or line == '':
+                        break
+            else:
+                orig_buffer.seek(0)
+                while True:
+                    line = orig_buffer.readline()
+                    self._file.write(line.replace('\n', os.linesep))
+                    if line == '\n' or line == '':
+                        break
+            while True:
+                buffer = orig_buffer.read(4096) # Buffer size is arbitrary.
+                if buffer == '':
+                    break
+                self._file.write(buffer.replace('\n', os.linesep))
+        elif isinstance(message, str):
+            body_start = message.find('\n\n') + 2
+            if body_start - 2 != -1:
+                self._file.write(message[:body_start].replace('\n',
+                                                              os.linesep))
+                self._file.write('*** EOOH ***' + os.linesep)
+                self._file.write(message[:body_start].replace('\n',
+                                                              os.linesep))
+                self._file.write(message[body_start:].replace('\n',
+                                                              os.linesep))
+            else:
+                self._file.write('*** EOOH ***' + os.linesep + os.linesep)
+                self._file.write(message.replace('\n', os.linesep))
+        elif hasattr(message, 'readline'):
+            original_pos = message.tell()
+            first_pass = True
+            while True:
+                line = message.readline()
+                self._file.write(line.replace('\n', os.linesep))
+                if line == '\n' or line == '':
+                    self._file.write('*** EOOH ***' + os.linesep)
+                    if first_pass:
+                        first_pass = False
+                        message.seek(original_pos)
+                    else:
+                        break
+            while True:
+                buffer = message.read(4096)     # Buffer size is arbitrary.
+                if buffer == '':
+                    break
+                self._file.write(buffer.replace('\n', os.linesep))
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+        stop = self._file.tell()
+        return (start, stop)
+
+
+class Message(email.Message.Message):
+    """Message with mailbox-format-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize a Message instance."""
+        if isinstance(message, email.Message.Message):
+            self._become_message(copy.deepcopy(message))
+            if isinstance(message, Message):
+                message._explain_to(self)
+        elif isinstance(message, str):
+            self._become_message(email.message_from_string(message))
+        elif hasattr(message, "read"):
+            self._become_message(email.message_from_file(message))
+        elif message is None:
+            email.Message.Message.__init__(self)
+        else:
+            raise TypeError('Invalid message type: %s' % type(message))
+
+    def _become_message(self, message):
+        """Assume the non-format-specific state of message."""
+        for name in ('_headers', '_unixfrom', '_payload', '_charset',
+                     'preamble', 'epilogue', 'defects', '_default_type'):
+            self.__dict__[name] = message.__dict__[name]
+
+    def _explain_to(self, message):
+        """Copy format-specific state to message insofar as possible."""
+        if isinstance(message, Message):
+            return  # There's nothing format-specific to explain.
+        else:
+            raise TypeError('Cannot convert to specified type')
+
+
+class MaildirMessage(Message):
+    """Message with Maildir-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize a MaildirMessage instance."""
+        self._subdir = 'new'
+        self._info = ''
+        self._date = time.time()
+        Message.__init__(self, message)
+
+    def get_subdir(self):
+        """Return 'new' or 'cur'."""
+        return self._subdir
+
+    def set_subdir(self, subdir):
+        """Set subdir to 'new' or 'cur'."""
+        if subdir == 'new' or subdir == 'cur':
+            self._subdir = subdir
+        else:
+            raise ValueError("subdir must be 'new' or 'cur': %s" % subdir)
+
+    def get_flags(self):
+        """Return as a string the flags that are set."""
+        if self._info.startswith('2,'):
+            return self._info[2:]
+        else:
+            return ''
+
+    def set_flags(self, flags):
+        """Set the given flags and unset all others."""
+        self._info = '2,' + ''.join(sorted(flags))
+
+    def add_flag(self, flag):
+        """Set the given flag(s) without changing others."""
+        self.set_flags(''.join(set(self.get_flags()) | set(flag)))
+
+    def remove_flag(self, flag):
+        """Unset the given string flag(s) without changing others."""
+        if self.get_flags() != '':
+            self.set_flags(''.join(set(self.get_flags()) - set(flag)))
+
+    def get_date(self):
+        """Return delivery date of message, in seconds since the epoch."""
+        return self._date
+
+    def set_date(self, date):
+        """Set delivery date of message, in seconds since the epoch."""
+        try:
+            self._date = float(date)
+        except ValueError:
+            raise TypeError("can't convert to float: %s" % date)
+
+    def get_info(self):
+        """Get the message's "info" as a string."""
+        return self._info
+
+    def set_info(self, info):
+        """Set the message's "info" string."""
+        if isinstance(info, str):
+            self._info = info
+        else:
+            raise TypeError('info must be a string: %s' % type(info))
+
+    def _explain_to(self, message):
+        """Copy Maildir-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            message.set_flags(self.get_flags())
+            message.set_subdir(self.get_subdir())
+            message.set_date(self.get_date())
+        elif isinstance(message, _mboxMMDFMessage):
+            flags = set(self.get_flags())
+            if 'S' in flags:
+                message.add_flag('R')
+            if self.get_subdir() == 'cur':
+                message.add_flag('O')
+            if 'T' in flags:
+                message.add_flag('D')
+            if 'F' in flags:
+                message.add_flag('F')
+            if 'R' in flags:
+                message.add_flag('A')
+            message.set_from('MAILER-DAEMON', time.gmtime(self.get_date()))
+        elif isinstance(message, MHMessage):
+            flags = set(self.get_flags())
+            if 'S' not in flags:
+                message.add_sequence('unseen')
+            if 'R' in flags:
+                message.add_sequence('replied')
+            if 'F' in flags:
+                message.add_sequence('flagged')
+        elif isinstance(message, BabylMessage):
+            flags = set(self.get_flags())
+            if 'S' not in flags:
+                message.add_label('unseen')
+            if 'T' in flags:
+                message.add_label('deleted')
+            if 'R' in flags:
+                message.add_label('answered')
+            if 'P' in flags:
+                message.add_label('forwarded')
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class _mboxMMDFMessage(Message):
+    """Message with mbox- or MMDF-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an mboxMMDFMessage instance."""
+        self.set_from('MAILER-DAEMON', True)
+        if isinstance(message, email.Message.Message):
+            unixfrom = message.get_unixfrom()
+            if unixfrom is not None and unixfrom.startswith('From '):
+                self.set_from(unixfrom[5:])
+        Message.__init__(self, message)
+
+    def get_from(self):
+        """Return contents of "From " line."""
+        return self._from
+
+    def set_from(self, from_, time_=None):
+        """Set "From " line, formatting and appending time_ if specified."""
+        if time_ is not None:
+            if time_ is True:
+                time_ = time.gmtime()
+            from_ += ' ' + time.asctime(time_)
+        self._from = from_
+
+    def get_flags(self):
+        """Return as a string the flags that are set."""
+        return self.get('Status', '') + self.get('X-Status', '')
+
+    def set_flags(self, flags):
+        """Set the given flags and unset all others."""
+        flags = set(flags)
+        status_flags, xstatus_flags = '', ''
+        for flag in ('R', 'O'):
+            if flag in flags:
+                status_flags += flag
+                flags.remove(flag)
+        for flag in ('D', 'F', 'A'):
+            if flag in flags:
+                xstatus_flags += flag
+                flags.remove(flag)
+        xstatus_flags += ''.join(sorted(flags))
+        try:
+            self.replace_header('Status', status_flags)
+        except KeyError:
+            self.add_header('Status', status_flags)
+        try:
+            self.replace_header('X-Status', xstatus_flags)
+        except KeyError:
+            self.add_header('X-Status', xstatus_flags)
+
+    def add_flag(self, flag):
+        """Set the given flag(s) without changing others."""
+        self.set_flags(''.join(set(self.get_flags()) | set(flag)))
+
+    def remove_flag(self, flag):
+        """Unset the given string flag(s) without changing others."""
+        if 'Status' in self or 'X-Status' in self:
+            self.set_flags(''.join(set(self.get_flags()) - set(flag)))
+
+    def _explain_to(self, message):
+        """Copy mbox- or MMDF-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            flags = set(self.get_flags())
+            if 'O' in flags:
+                message.set_subdir('cur')
+            if 'F' in flags:
+                message.add_flag('F')
+            if 'A' in flags:
+                message.add_flag('R')
+            if 'R' in flags:
+                message.add_flag('S')
+            if 'D' in flags:
+                message.add_flag('T')
+            del message['status']
+            del message['x-status']
+            maybe_date = ' '.join(self.get_from().split()[-5:])
+            try:
+                message.set_date(calendar.timegm(time.strptime(maybe_date,
+                                                      '%a %b %d %H:%M:%S %Y')))
+            except (ValueError, OverflowError):
+                pass
+        elif isinstance(message, _mboxMMDFMessage):
+            message.set_flags(self.get_flags())
+            message.set_from(self.get_from())
+        elif isinstance(message, MHMessage):
+            flags = set(self.get_flags())
+            if 'R' not in flags:
+                message.add_sequence('unseen')
+            if 'A' in flags:
+                message.add_sequence('replied')
+            if 'F' in flags:
+                message.add_sequence('flagged')
+            del message['status']
+            del message['x-status']
+        elif isinstance(message, BabylMessage):
+            flags = set(self.get_flags())
+            if 'R' not in flags:
+                message.add_label('unseen')
+            if 'D' in flags:
+                message.add_label('deleted')
+            if 'A' in flags:
+                message.add_label('answered')
+            del message['status']
+            del message['x-status']
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class mboxMessage(_mboxMMDFMessage):
+    """Message with mbox-specific properties."""
+
+
+class MHMessage(Message):
+    """Message with MH-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an MHMessage instance."""
+        self._sequences = []
+        Message.__init__(self, message)
+
+    def get_sequences(self):
+        """Return a list of sequences that include the message."""
+        return self._sequences[:]
+
+    def set_sequences(self, sequences):
+        """Set the list of sequences that include the message."""
+        self._sequences = list(sequences)
+
+    def add_sequence(self, sequence):
+        """Add sequence to list of sequences including the message."""
+        if isinstance(sequence, str):
+            if not sequence in self._sequences:
+                self._sequences.append(sequence)
+        else:
+            raise TypeError('sequence must be a string: %s' % type(sequence))
+
+    def remove_sequence(self, sequence):
+        """Remove sequence from the list of sequences including the message."""
+        try:
+            self._sequences.remove(sequence)
+        except ValueError:
+            pass
+
+    def _explain_to(self, message):
+        """Copy MH-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' in sequences:
+                message.set_subdir('cur')
+            else:
+                message.set_subdir('cur')
+                message.add_flag('S')
+            if 'flagged' in sequences:
+                message.add_flag('F')
+            if 'replied' in sequences:
+                message.add_flag('R')
+        elif isinstance(message, _mboxMMDFMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' not in sequences:
+                message.add_flag('RO')
+            else:
+                message.add_flag('O')
+            if 'flagged' in sequences:
+                message.add_flag('F')
+            if 'replied' in sequences:
+                message.add_flag('A')
+        elif isinstance(message, MHMessage):
+            for sequence in self.get_sequences():
+                message.add_sequence(sequence)
+        elif isinstance(message, BabylMessage):
+            sequences = set(self.get_sequences())
+            if 'unseen' in sequences:
+                message.add_label('unseen')
+            if 'replied' in sequences:
+                message.add_label('answered')
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class BabylMessage(Message):
+    """Message with Babyl-specific properties."""
+
+    def __init__(self, message=None):
+        """Initialize an BabylMessage instance."""
+        self._labels = []
+        self._visible = Message()
+        Message.__init__(self, message)
+
+    def get_labels(self):
+        """Return a list of labels on the message."""
+        return self._labels[:]
+
+    def set_labels(self, labels):
+        """Set the list of labels on the message."""
+        self._labels = list(labels)
+
+    def add_label(self, label):
+        """Add label to list of labels on the message."""
+        if isinstance(label, str):
+            if label not in self._labels:
+                self._labels.append(label)
+        else:
+            raise TypeError('label must be a string: %s' % type(label))
+
+    def remove_label(self, label):
+        """Remove label from the list of labels on the message."""
+        try:
+            self._labels.remove(label)
+        except ValueError:
+            pass
+    
+    def get_visible(self):
+        """Return a Message representation of visible headers."""
+        return Message(self._visible)
+
+    def set_visible(self, visible):
+        """Set the Message representation of visible headers."""
+        self._visible = Message(visible)
+
+    def update_visible(self):
+        """Update and/or sensibly generate a set of visible headers."""
+        for header in self._visible.keys():
+            if header in self:
+                self._visible.replace_header(header, self[header])
+            else:
+                del self._visible[header]
+        for header in ('Date', 'From', 'Reply-To', 'To', 'CC', 'Subject'):
+            if header in self and header not in self._visible:
+                self._visible[header] = self[header]
+
+    def _explain_to(self, message):
+        """Copy Babyl-specific state to message insofar as possible."""
+        if isinstance(message, MaildirMessage):
+            labels = set(self.get_labels())
+            if 'unseen' in labels:
+                message.set_subdir('cur')
+            else:
+                message.set_subdir('cur')
+                message.add_flag('S')
+            if 'forwarded' in labels or 'resent' in labels:
+                message.add_flag('P')
+            if 'answered' in labels:
+                message.add_flag('R')
+            if 'deleted' in labels:
+                message.add_flag('T')
+        elif isinstance(message, _mboxMMDFMessage):
+            labels = set(self.get_labels())
+            if 'unseen' not in labels:
+                message.add_flag('RO')
+            else:
+                message.add_flag('O')
+            if 'deleted' in labels:
+                message.add_flag('D')
+            if 'answered' in labels:
+                message.add_flag('A')
+        elif isinstance(message, MHMessage):
+            labels = set(self.get_labels())
+            if 'unseen' in labels:
+                message.add_sequence('unseen')
+            if 'answered' in labels:
+                message.add_sequence('replied')
+        elif isinstance(message, BabylMessage):
+            message.set_visible(self.get_visible())
+            for label in self.get_labels():
+                message.add_label(label)
+        elif isinstance(message, Message):
+            pass
+        else:
+            raise TypeError('Cannot convert to specified type: %s' %
+                            type(message))
+
+
+class MMDFMessage(_mboxMMDFMessage):
+    """Message with MMDF-specific properties."""
+
+
+class _ProxyFile:
+    """A read-only wrapper of a file."""
+
+    def __init__(self, f, pos=None):
+        """Initialize a _ProxyFile."""
+        self._file = f
+        if pos is None:
+            self._pos = f.tell()
+        else:
+            self._pos = pos
+
+    def read(self, size=None):
+        """Read bytes."""
+        return self._read(size, self._file.read)
+
+    def readline(self, size=None):
+        """Read a line."""
+        return self._read(size, self._file.readline)
+
+    def readlines(self, sizehint=None):
+        """Read multiple lines."""
+        result = []
+        for line in self:
+            result.append(line)
+            if sizehint is not None:
+                sizehint -= len(line)
+                if sizehint <= 0:
+                    break
+        return result
+
+    def __iter__(self):
+        """Iterate over lines."""
+        return iter(self.readline, "")
+
+    def tell(self):
+        """Return the position."""
+        return self._pos
+
+    def seek(self, offset, whence=0):
+        """Change position."""
+        if whence == 1:
+            self._file.seek(self._pos)
+        self._file.seek(offset, whence)
+        self._pos = self._file.tell()
+
+    def close(self):
+        """Close the file."""
+        del self._file
+
+    def _read(self, size, read_method):
+        """Read size bytes using read_method."""
+        if size is None:
+            size = -1
+        self._file.seek(self._pos)
+        result = read_method(size)
+        self._pos = self._file.tell()
+        return result
+
+
+class _PartialFile(_ProxyFile):
+    """A read-only wrapper of part of a file."""
+
+    def __init__(self, f, start=None, stop=None):
+        """Initialize a _PartialFile."""
+        _ProxyFile.__init__(self, f, start)
+        self._start = start
+        self._stop = stop
+
+    def tell(self):
+        """Return the position with respect to start."""
+        return _ProxyFile.tell(self) - self._start
+
+    def seek(self, offset, whence=0):
+        """Change position, possibly with respect to start or stop."""
+        if whence == 0:
+            self._pos = self._start
+            whence = 1
+        elif whence == 2:
+            self._pos = self._stop
+            whence = 1
+        _ProxyFile.seek(self, offset, whence)
+
+    def _read(self, size, read_method):
+        """Read size bytes using read_method, honoring start and stop."""
+        remaining = self._stop - self._pos
+        if remaining <= 0:
+            return ''
+        if size is None or size < 0 or size > remaining:
+            size = remaining
+        return _ProxyFile._read(self, size, read_method)
+
+
+def _lock_file(f, dotlock=True):
+    """Lock file f using lockf, flock, and dot locking."""
+    dotlock_done = False
+    try:
+        if fcntl:
+            try:
+                fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
+            except IOError, e:
+                if e.errno == errno.EAGAIN:
+                    raise ExternalClashError('lockf: lock unavailable: %s' %
+                                             f.name)
+                else:
+                    raise
+            try:
+                fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
+            except IOError, e:
+                if e.errno == errno.EWOULDBLOCK:
+                    raise ExternalClashError('flock: lock unavailable: %s' %
+                                             f.name)
+                else:
+                    raise
+        if dotlock:
+            try:
+                pre_lock = _create_temporary(f.name + '.lock')
+                pre_lock.close()
+            except IOError, e:
+                if e.errno == errno.EACCES:
+                    return  # Without write access, just skip dotlocking.
+                else:
+                    raise
+            try:
+                if hasattr(os, 'link'):
+                    os.link(pre_lock.name, f.name + '.lock')
+                    dotlock_done = True
+                    os.unlink(pre_lock.name)
+                else:
+                    os.rename(pre_lock.name, f.name + '.lock')
+                    dotlock_done = True
+            except OSError, e:
+                if e.errno == errno.EEXIST:
+                    os.remove(pre_lock.name)
+                    raise ExternalClashError('dot lock unavailable: %s' % 
+                                             f.name)
+                else:
+                    raise
+    except:
+        if fcntl:
+            fcntl.lockf(f, fcntl.LOCK_UN)
+            fcntl.flock(f, fcntl.LOCK_UN)
+        if dotlock_done:
+            os.remove(f.name + '.lock')
+        raise
+
+def _unlock_file(f):
+    """Unlock file f using lockf, flock, and dot locking."""
+    if fcntl:
+        fcntl.lockf(f, fcntl.LOCK_UN)
+        fcntl.flock(f, fcntl.LOCK_UN)
+    if os.path.exists(f.name + '.lock'):
+        os.remove(f.name + '.lock')
+
+def _create_carefully(path):
+    """Create a file if it doesn't exist and open for reading and writing."""
+    fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+    try:
+        return file(path, 'rb+')
+    finally:
+        os.close(fd)
+
+def _create_temporary(path):
+    """Create a temp file based on path and open for reading and writing."""
+    return _create_carefully('%s.%s.%s.%s' % (path, int(time.time()),
+                                              socket.gethostname(),
+                                              os.getpid()))
+
+
+## Start: classes from the original module (for backward compatibility).
+
+# Note that the Maildir class, whose name is unchanged, itself offers a next()
+# method for backward compatibility.
 
 class _Mailbox:
 
@@ -32,62 +1903,7 @@
             self.seekp = stop = self.fp.tell()
             if start != stop:
                 break
-        return self.factory(_Subfile(self.fp, start, stop))
-
-
-class _Subfile:
-
-    def __init__(self, fp, start, stop):
-        self.fp = fp
-        self.start = start
-        self.stop = stop
-        self.pos = self.start
-
-
-    def _read(self, length, read_function):
-        if self.pos >= self.stop:
-            return ''
-        remaining = self.stop - self.pos
-        if length is None or length < 0 or length > remaining:
-            length = remaining
-        self.fp.seek(self.pos)
-        data = read_function(length)
-        self.pos = self.fp.tell()
-        return data
-
-    def read(self, length = None):
-        return self._read(length, self.fp.read)
-
-    def readline(self, length = None):
-        return self._read(length, self.fp.readline)
-
-    def readlines(self, sizehint = -1):
-        lines = []
-        while 1:
-            line = self.readline()
-            if not line:
-                break
-            lines.append(line)
-            if sizehint >= 0:
-                sizehint = sizehint - len(line)
-                if sizehint <= 0:
-                    break
-        return lines
-
-    def tell(self):
-        return self.pos - self.start
-
-    def seek(self, pos, whence=0):
-        if whence == 0:
-            self.pos = self.start + pos
-        elif whence == 1:
-            self.pos = self.pos + pos
-        elif whence == 2:
-            self.pos = self.stop + pos
-
-    def close(self):
-        del self.fp
-
+        return self.factory(_PartialFile(self.fp, start, stop))
 
 # Recommended to use PortableUnixMailbox instead!
 class UnixMailbox(_Mailbox):
@@ -213,36 +2029,6 @@
         return msg
 
 
-class Maildir:
-    # Qmail directory mailbox
-
-    def __init__(self, dirname, factory=rfc822.Message):
-        self.dirname = dirname
-        self.factory = factory
-
-        # check for new mail
-        newdir = os.path.join(self.dirname, 'new')
-        boxes = [os.path.join(newdir, f)
-                 for f in os.listdir(newdir) if f[0] != '.']
-
-        # Now check for current mail in this maildir
-        curdir = os.path.join(self.dirname, 'cur')
-        boxes += [os.path.join(curdir, f)
-                  for f in os.listdir(curdir) if f[0] != '.']
-        boxes.reverse()
-        self.boxes = boxes
-
-    def __iter__(self):
-        return iter(self.next, None)
-
-    def next(self):
-        if not self.boxes:
-            return None
-        fn = self.boxes.pop()
-        fp = open(fn)
-        return self.factory(fp)
-
-
 class BabylMailbox(_Mailbox):
 
     def _search_start(self):
@@ -263,59 +2049,20 @@
                 self.fp.seek(pos)
                 return
 
-
-def _test():
-    import sys
-
-    args = sys.argv[1:]
-    if not args:
-        for key in 'MAILDIR', 'MAIL', 'LOGNAME', 'USER':
-            if key in os.environ:
-                mbox = os.environ[key]
-                break
-        else:
-            print "$MAIL, $LOGNAME nor $USER set -- who are you?"
-            return
-    else:
-        mbox = args[0]
-    if mbox[:1] == '+':
-        mbox = os.environ['HOME'] + '/Mail/' + mbox[1:]
-    elif not '/' in mbox:
-        if os.path.isfile('/var/mail/' + mbox):
-            mbox = '/var/mail/' + mbox
-        else:
-            mbox = '/usr/mail/' + mbox
-    if os.path.isdir(mbox):
-        if os.path.isdir(os.path.join(mbox, 'cur')):
-            mb = Maildir(mbox)
-        else:
-            mb = MHMailbox(mbox)
-    else:
-        fp = open(mbox, 'r')
-        mb = PortableUnixMailbox(fp)
-
-    msgs = []
-    while 1:
-        msg = mb.next()
-        if msg is None:
-            break
-        msgs.append(msg)
-        if len(args) <= 1:
-            msg.fp = None
-    if len(args) > 1:
-        num = int(args[1])
-        print 'Message %d body:'%num
-        msg = msgs[num-1]
-        msg.rewindbody()
-        sys.stdout.write(msg.fp.read())
-    else:
-        print 'Mailbox',mbox,'has',len(msgs),'messages:'
-        for msg in msgs:
-            f = msg.getheader('from') or ""
-            s = msg.getheader('subject') or ""
-            d = msg.getheader('date') or ""
-            print '-%20.20s   %20.20s   %-30.30s'%(f, d[5:], s)
+## End: classes from the original module (for backward compatibility).
 
 
-if __name__ == '__main__':
-    _test()
+class Error(Exception):
+    """Raised for module-specific errors."""
+
+class NoSuchMailboxError(Error):
+    """The specified mailbox does not exist and won't be created."""
+
+class NotEmptyError(Error):
+    """The specified mailbox is not empty and deletion was requested."""
+
+class ExternalClashError(Error):
+    """Another process caused an action to fail."""
+
+class FormatError(Error):
+    """A file appears to have an invalid format."""
