diff --git a/src/zc/buildout/buildout.py b/src/zc/buildout/buildout.py
index 961057348359b5ac882e928af083b7775a8f0253..b1478180f36613dc660868a63de7fe46c138ecbe 100644
--- a/src/zc/buildout/buildout.py
+++ b/src/zc/buildout/buildout.py
@@ -60,6 +60,9 @@ class Buildout(dict):
     def __init__(self, config_file, cloptions):
         config_file = os.path.abspath(config_file)
         self._config_file = config_file
+        if not os.path.exists(config_file):
+            print 'Warning: creating', config_file
+            open(config_file, 'w').write('[buildout]\nparts = \n')
 
         super(Buildout, self).__init__()
 
@@ -376,10 +379,15 @@ class Buildout(dict):
     def _read_installed_part_options(self):
         old = self._installed_path()
         if os.path.isfile(old):
-            parser = ConfigParser.SafeConfigParser()
+            parser = ConfigParser.SafeConfigParser(_spacey_defaults)
             parser.read(old)
             return dict([
-                (section, Options(self, section, parser.items(section)))
+                (section,
+                 Options(self, section,
+                         [item for item in parser.items(section)
+                          if item[0] not in _spacey_defaults]
+                         )
+                 )
                 for section in parser.sections()])
         else:
             return {'buildout': Options(self, 'buildout', {'parts': ''})}
@@ -453,13 +461,44 @@ class Buildout(dict):
             for section in sections:
                 _save_options(section, self[section], sys.stdout)
             print    
-        
+
+_spacey_nl = re.compile('^[ \t\r\f\v]+'
+                        '|''[ \t\r\f\v]*\n[ \t\r\f\v\n]*'
+                        '|'
+                        '[ \t\r\f\v]+$'
+                        )
+
+def _quote_spacey_nl(match):
+    match = match.group(0).split('\n', 1)
+    result = '\n\t'.join(
+        [(s
+          .replace(' ', '%(__buildout_space__)s')
+          .replace('\r', '%(__buildout_space_r__)s')
+          .replace('\f', '%(__buildout_space_f__)s')
+          .replace('\v', '%(__buildout_space_v__)s')
+          .replace('\n', '%(__buildout_space_n__)s')
+          )
+         for s in match]
+        )
+    return result
+
+_spacey_defaults = dict(
+    __buildout_space__   = ' ',
+    __buildout_space_r__ = '\r',
+    __buildout_space_f__ = '\f',
+    __buildout_space_v__ = '\v',
+    __buildout_space_n__ = '\n',
+    )
+
 def _save_options(section, options, f):
     print >>f, '[%s]' % section
     items = options.items()
     items.sort()
     for option, value in items:
-        print >>f, option, '=', str(value).replace('\n', '\n\t')
+        value = value.replace('%', '%%')
+        value = _spacey_nl.sub(_quote_spacey_nl, value)
+        print >>f, option, '=', value
+            
     
 
 def _open(base, filename, seen):
diff --git a/src/zc/buildout/buildout.txt b/src/zc/buildout/buildout.txt
index e0834483f7d275ae27dcd09985d5a1d8c4149288..99ebaf28df2634e87f8ed413a7c397db9a28e4a0 100644
--- a/src/zc/buildout/buildout.txt
+++ b/src/zc/buildout/buildout.txt
@@ -1066,7 +1066,7 @@ database is shown.
     eggs-directory = /tmp/sample-buildout/eggs
     executable = /usr/local/bin/python2.3
     installed = /tmp/sample-buildout/.installed.cfg
-    log-format = %(name)s: %(message)s
+    log-format = %%(name)s: %%(message)s
     log-level = WARNING
     parts = 
     parts-directory = /tmp/sample-buildout/parts
@@ -1141,18 +1141,16 @@ Bootstrapping
 
 If zc.buildout is installed, you can use it to create a new buildout
 with it's own local copies of zc.buildout and setuptools and with
-local buildout scripts.  There must be an existing setup.cfg:
+local buildout scripts. 
 
     >>> sample_bootstrapped = mkdtemp('sample-bootstrapped')
-    >>> write(sample_bootstrapped, 'setup.cfg',
-    ... '''
-    ... [buildout]
-    ... parts = foo this will not be read :)
-    ... ''')
 
     >>> print system(buildout
     ...              +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
     ...              +' bootstrap'),
+    Warning: creating /sample-bootstrapped/setup.cfg
+
+Note that a basic setup.cfg was created for us.
 
     >>> ls(sample_bootstrapped)
     d  bin
@@ -1173,7 +1171,7 @@ local buildout scripts.  There must be an existing setup.cfg:
 
 
 Note that, in this example, we were using a development egg for the
-buildout, and the ac.buildout egg ended up as an egg link.
+buildout, and the zc.buildout egg ended up as an egg link.
 
 Also not that the buildout script was installed but not run.  To run
 the buildout, we'd have to run the installed buildout script.
diff --git a/src/zc/buildout/tests.py b/src/zc/buildout/tests.py
index ef44c2c4738021921559471da99bee17ce442e1c..5c0260e5660a6e7afed21710f60670885d236811 100644
--- a/src/zc/buildout/tests.py
+++ b/src/zc/buildout/tests.py
@@ -61,6 +61,71 @@ It is an error to create a variable-reference cycle:
            [('buildout', 'y'), ('buildout', 'z'), ('buildout', 'x')],
            ('buildout', 'y'))
 """
+ 
+def test_comparing_saved_options_with_funny_characters():
+    """
+    If an option has newlines, extra/odd spaces or a %, we need to make
+    sure the comparison with the saved value works correctly.
+
+    >>> mkdir(sample_buildout, 'recipes')
+    >>> write(sample_buildout, 'recipes', 'debug.py', 
+    ... '''
+    ... class Debug:
+    ...     def __init__(self, buildout, name, options):
+    ...         options['debug'] = \"\"\"  <zodb>
+    ...
+    ...   <filestorage>
+    ...     path foo
+    ...   </filestorage>
+    ...
+    ... </zodb>  
+    ...      \"\"\"
+    ...         options['debug2'] = '  x  '
+    ...         options['debug3'] = '42'
+    ...         options['format'] = '%3d'
+    ...
+    ...     def install(self):
+    ...         open('t', 'w').write('t')
+    ...         return 't'
+    ... ''')
+
+
+    >>> write(sample_buildout, 'recipes', 'setup.py',
+    ... '''
+    ... from setuptools import setup
+    ... setup(
+    ...     name = "recipes",
+    ...     entry_points = {'zc.buildout': ['default = debug:Debug']},
+    ...     )
+    ... ''')
+
+    >>> write(sample_buildout, 'recipes', 'README.txt', " ")
+
+    >>> write(sample_buildout, 'buildout.cfg',
+    ... '''
+    ... [buildout]
+    ... develop = recipes
+    ... parts = debug
+    ...
+    ... [debug]
+    ... recipe = recipes
+    ... ''')
+
+    >>> os.chdir(sample_buildout)
+    >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
+
+    >>> print system(buildout+' -v'), # doctest: +ELLIPSIS
+    buildout: Running ...setup.py -q develop ...
+    buildout: Installing debug
+
+If we run the buildout again, we shoudn't get a message about
+uninstalling anything because the configuration hasn't changed.
+
+    >>> print system(buildout+' -v'),
+    buildout: Running setup.py -q develop ...
+    buildout: Installing debug
+"""
+
 
 def linkerSetUp(test):
     zc.buildout.testing.buildoutSetUp(test, clear_home=False)
@@ -136,6 +201,7 @@ def test_suite():
                (re.compile('executable = \S+python\S*'),
                 'executable = python'),
                (re.compile('setuptools-\S+[.]egg'), 'setuptools.egg'),
+               (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
                ])
             ),
         
@@ -154,7 +220,13 @@ def test_suite():
             ),
         doctest.DocTestSuite(
             setUp=zc.buildout.testing.buildoutSetUp,
-            tearDown=zc.buildout.testing.buildoutTearDown),
+            tearDown=zc.buildout.testing.buildoutTearDown,
+
+            checker=PythonNormalizing([
+               (re.compile("buildout: Running \S*setup.py"),
+                'buildout: Running setup.py'),
+               ]),
+            )
         ))
 
 if __name__ == '__main__':