Merge of the folding-reimpl-branch.  Specific changes,

_handle_multipart(): Ensure that if the preamble exists but does not
end in a newline, a newline is still added.  Without this, the
boundary separator will end up on the preamble line, breaking the MIME
structure.

_make_boundary(): Handle differences in the decimal point character
based on the locale.
diff --git a/Lib/email/Generator.py b/Lib/email/Generator.py
index 58e2f91..4f455a4 100644
--- a/Lib/email/Generator.py
+++ b/Lib/email/Generator.py
@@ -4,14 +4,16 @@
 """Classes to generate plain text from a message object tree.
 """
 
-import time
 import re
+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
@@ -258,6 +260,14 @@
         # Write out any preamble
         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, '--' + boundary
@@ -364,7 +374,8 @@
 def _make_boundary(text=None):
     # Craft a random boundary.  If text is given, ensure that the chosen
     # boundary doesn't appear in the text.
-    boundary = ('=' * 15) + repr(random.random()).split('.')[1] + '=='
+    dp = locale.localeconv().get('decimal_point', '.')
+    boundary = ('=' * 15) + repr(random.random()).split(dp)[1] + '=='
     if text is None:
         return boundary
     b = boundary