Update to Python 2.3, getting rid of backward compatiblity crud.  Get rid of a
bunch of module globals that aren't used.

__maxheaderlen -> _maxheaderlen

_handle_multipart(): This should be more RFC compliant now, and does match the
updated/fixed semantics for preamble and epilogue.
diff --git a/Lib/email/Generator.py b/Lib/email/Generator.py
index 56d44ea5..7fe634f 100644
--- a/Lib/email/Generator.py
+++ b/Lib/email/Generator.py
@@ -1,5 +1,5 @@
-# Copyright (C) 2001,2002 Python Software Foundation
-# Author: barry@zope.com (Barry Warsaw)
+# Copyright (C) 2001-2004 Python Software Foundation
+# Author: barry@python.org (Barry Warsaw)
 
 """Classes to generate plain text from a message object tree.
 """
@@ -7,39 +7,18 @@
 import re
 import sys
 import time
-import locale
 import random
-
-from types import ListType, StringType
 from cStringIO import StringIO
 
 from email.Header import Header
-from email.Parser import NLCRE
 
-try:
-    from email._compat22 import _isstring
-except SyntaxError:
-    from email._compat21 import _isstring
-
-try:
-    True, False
-except NameError:
-    True = 1
-    False = 0
-
-EMPTYSTRING = ''
-SEMISPACE = '; '
-BAR = '|'
 UNDERSCORE = '_'
 NL = '\n'
-NLTAB = '\n\t'
-SEMINLTAB = ';\n\t'
-SPACE8 = ' ' * 8
 
 fcre = re.compile(r'^From ', re.MULTILINE)
 
 def _is8bitstring(s):
-    if isinstance(s, StringType):
+    if isinstance(s, str):
         try:
             unicode(s, 'us-ascii')
         except UnicodeError:
@@ -77,7 +56,7 @@
         """
         self._fp = outfp
         self._mangle_from_ = mangle_from_
-        self.__maxheaderlen = maxheaderlen
+        self._maxheaderlen = maxheaderlen
 
     def write(self, s):
         # Just delegate to the file object
@@ -106,7 +85,7 @@
 
     def clone(self, fp):
         """Clone this generator with the exact same options."""
-        return self.__class__(fp, self._mangle_from_, self.__maxheaderlen)
+        return self.__class__(fp, self._mangle_from_, self._maxheaderlen)
 
     #
     # Protected interface - undocumented ;/
@@ -162,7 +141,7 @@
     def _write_headers(self, msg):
         for h, v in msg.items():
             print >> self._fp, '%s:' % h,
-            if self.__maxheaderlen == 0:
+            if self._maxheaderlen == 0:
                 # Explicit no-wrapping
                 print >> self._fp, v
             elif isinstance(v, Header):
@@ -179,7 +158,7 @@
             else:
                 # Header's got lots of smarts, so use it.
                 print >> self._fp, Header(
-                    v, maxlinelen=self.__maxheaderlen,
+                    v, maxlinelen=self._maxheaderlen,
                     header_name=h, continuation_ws='\t').encode()
         # A blank line always separates headers from body
         print >> self._fp
@@ -195,7 +174,7 @@
         cset = msg.get_charset()
         if cset is not None:
             payload = cset.body_encode(payload)
-        if not _isstring(payload):
+        if not isinstance(payload, basestring):
             raise TypeError, 'string payload expected: %s' % type(payload)
         if self._mangle_from_:
             payload = fcre.sub('>From ', payload)
@@ -211,17 +190,12 @@
         msgtexts = []
         subparts = msg.get_payload()
         if subparts is None:
-            # Nothing has ever been attached
-            boundary = msg.get_boundary(failobj=_make_boundary())
-            print >> self._fp, '--' + boundary
-            print >> self._fp, '\n'
-            print >> self._fp, '--' + boundary + '--'
-            return
-        elif _isstring(subparts):
+            subparts = []
+        elif isinstance(subparts, basestring):
             # e.g. a non-strict parse of a message with no starting boundary.
             self._fp.write(subparts)
             return
-        elif not isinstance(subparts, ListType):
+        elif not isinstance(subparts, list):
             # Scalar payload
             subparts = [subparts]
         for part in subparts:
@@ -242,28 +216,26 @@
         # suite.
         if msg.get_boundary() <> boundary:
             msg.set_boundary(boundary)
-        # Write out any preamble
+        # If there's a preamble, write it out, with a trailing CRLF
         if msg.preamble is not None:
-            self._fp.write(msg.preamble)
-            # If preamble is the empty string, the length of the split will be
-            # 1, but the last element will be the empty string.  If it's
-            # anything else but does not end in a line separator, the length
-            # will be > 1 and not end in an empty string.  We need to
-            # guarantee a newline after the preamble, but don't add too many.
-            plines = NLCRE.split(msg.preamble)
-            if plines <> [''] and plines[-1] <> '':
-                self._fp.write('\n')
-        # First boundary is a bit different; it doesn't have a leading extra
-        # newline.
+            print >> self._fp, msg.preamble
+        # dash-boundary transport-padding CRLF
         print >> self._fp, '--' + boundary
-        # Join and write the individual parts
-        joiner = '\n--' + boundary + '\n'
-        self._fp.write(joiner.join(msgtexts))
-        print >> self._fp, '\n--' + boundary + '--',
-        # Write out any epilogue
+        # body-part
+        if msgtexts:
+            self._fp.write(msgtexts.pop(0))
+        # *encapsulation
+        # --> delimiter transport-padding
+        # --> CRLF body-part
+        for body_part in msgtexts:
+            # delimiter transport-padding CRLF
+            print >> self._fp, '\n--' + boundary
+            # body-part
+            self._fp.write(body_part)
+        # close-delimiter transport-padding
+        self._fp.write('\n--' + boundary + '--')
         if msg.epilogue is not None:
-            if not msg.epilogue.startswith('\n'):
-                print >> self._fp
+            print >> self._fp
             self._fp.write(msg.epilogue)
 
     def _handle_message_delivery_status(self, msg):