The usual.
diff --git a/Lib/dos-8x3/configpa.py b/Lib/dos-8x3/configpa.py
index 16d18d2..5043687 100644
--- a/Lib/dos-8x3/configpa.py
+++ b/Lib/dos-8x3/configpa.py
@@ -91,6 +91,8 @@
 
 DEFAULTSECT = "DEFAULT"
 
+MAX_INTERPOLATION_DEPTH = 10
+
 
 
 # exception classes
@@ -130,15 +132,16 @@
         self.option = option
         self.section = section
 
-class MissingSectionHeaderError(Error):
-    def __init__(self, filename, lineno, line):
-        Error.__init__(
-            self,
-            'File contains no section headers.\nfile: %s, line: %d\n%s' %
-            (filename, lineno, line))
-        self.filename = filename
-        self.lineno = lineno
-        self.line = line
+class InterpolationDepthError(Error):
+    def __init__(self, option, section, rawval):
+        Error.__init__(self,
+                       "Value interpolation too deeply recursive:\n"
+                       "\tsection: [%s]\n"
+                       "\toption : %s\n"
+                       "\trawval : %s\n"
+                       % (section, option, rawval))
+        self.option = option
+        self.section = section
 
 class ParsingError(Error):
     def __init__(self, filename):
@@ -150,6 +153,16 @@
         self.errors.append((lineno, line))
         self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
 
+class MissingSectionHeaderError(ParsingError):
+    def __init__(self, filename, lineno, line):
+        Error.__init__(
+            self,
+            'File contains no section headers.\nfile: %s, line: %d\n%s' %
+            (filename, lineno, line))
+        self.filename = filename
+        self.lineno = lineno
+        self.line = line
+
 
 
 class ConfigParser:
@@ -183,7 +196,7 @@
 
         The DEFAULT section is not acknowledged.
         """
-        return self.__sections.has_key(section)
+        return section in self.sections()
 
     def options(self, section):
         """Return a list of option names for the given section name."""
@@ -192,15 +205,13 @@
         except KeyError:
             raise NoSectionError(section)
         opts.update(self.__defaults)
+        if opts.has_key('__name__'):
+            del opts['__name__']
         return opts.keys()
 
     def has_option(self, section, option):
         """Return whether the given section has the given option."""
-        try:
-            opts = self.__sections[section]
-        except KeyError:
-            raise NoSectionError(section)
-        return opts.has_key(option)
+        return option in self.options(section)
 
     def read(self, filenames):
         """Read and parse a filename or a list of filenames.
@@ -266,10 +277,11 @@
             rawval = d[option]
         except KeyError:
             raise NoOptionError(option, section)
-        # do the string interpolation
+
         if raw:
             return rawval
 
+        # do the string interpolation
         value = rawval                  # Make it a pretty variable name
         depth = 0                       
         while depth < 10:               # Loop through this until it's done
@@ -280,7 +292,10 @@
                 except KeyError, key:
                     raise InterpolationError(key, option, section, rawval)
             else:
-                return value
+                break
+        if value.find("%(") >= 0:
+            raise InterpolationDepthError(option, section, rawval)
+        return value
     
     def __get(self, section, conv, option):
         return conv(self.get(section, option))
@@ -365,7 +380,7 @@
     # of \w, _ is allowed in section header names.
     SECTCRE = re.compile(
         r'\['                                 # [
-        r'(?P<header>[-\w_.*,(){}]+)'         # a lot of stuff found by IvL
+        r'(?P<header>[-\w_.*,(){} ]+)'        # a lot of stuff found by IvL
         r'\]'                                 # ]
         )
     OPTCRE = re.compile(
diff --git a/Lib/dos-8x3/mimetool.py b/Lib/dos-8x3/mimetool.py
index 27996e0..da955af 100755
--- a/Lib/dos-8x3/mimetool.py
+++ b/Lib/dos-8x3/mimetool.py
@@ -141,7 +141,7 @@
 		import uu
 		return uu.decode(input, output)
 	if encoding in ('7bit', '8bit'):
-		output.write(input.read())
+		return output.write(input.read())
 	if decodetab.has_key(encoding):
 		pipethrough(input, decodetab[encoding], output)
 	else:
@@ -160,7 +160,7 @@
 		import uu
 		return uu.encode(input, output)
 	if encoding in ('7bit', '8bit'):
-		output.write(input.read())
+		return output.write(input.read())
 	if encodetab.has_key(encoding):
 		pipethrough(input, encodetab[encoding], output)
 	else:
diff --git a/Lib/dos-8x3/posixpat.py b/Lib/dos-8x3/posixpat.py
index f7e0161..2826604 100755
--- a/Lib/dos-8x3/posixpat.py
+++ b/Lib/dos-8x3/posixpat.py
@@ -56,9 +56,8 @@
 
 def split(p):
     """Split a pathname.  Returns tuple "(head, tail)" where "tail" is 
-everything after the final slash.  Either part may be empty"""
-    import string
-    i = string.rfind(p, '/') + 1
+    everything after the final slash.  Either part may be empty."""
+    i = p.rfind('/') + 1
     head, tail = p[:i], p[i:]
     if head and head <> '/'*len(head):
         while head[-1] == '/':
@@ -73,7 +72,7 @@
 
 def splitext(p):
     """Split the extension from a pathname.  Extension is everything from the
-last dot to the end.  Returns "(root, ext)", either part may be empty"""
+    last dot to the end.  Returns "(root, ext)", either part may be empty."""
     root, ext = '', ''
     for c in p:
         if c == '/':
@@ -95,7 +94,7 @@
 
 def splitdrive(p):
     """Split a pathname into drive and path. On Posix, drive is always 
-empty"""
+    empty."""
     return '', p
 
 
@@ -255,9 +254,9 @@
 
 def walk(top, func, arg):
     """walk(top,func,arg) calls func(arg, d, files) for each directory "d" 
-in the tree  rooted at "top" (including "top" itself).  "files" is a list
-of all the files and subdirs in directory "d".
-"""
+    in the tree  rooted at "top" (including "top" itself).  "files" is a list
+    of all the files and subdirs in directory "d".
+    """
     try:
         names = os.listdir(top)
     except os.error:
@@ -281,12 +280,12 @@
 
 def expanduser(path):
     """Expand ~ and ~user constructions.  If user or $HOME is unknown, 
-do nothing"""
+    do nothing."""
     if path[:1] <> '~':
         return path
     i, n = 1, len(path)
     while i < n and path[i] <> '/':
-        i = i+1
+        i = i + 1
     if i == 1:
         if not os.environ.has_key('HOME'):
             return path
@@ -298,7 +297,7 @@
         except KeyError:
             return path
         userhome = pwent[5]
-    if userhome[-1:] == '/': i = i+1
+    if userhome[-1:] == '/': i = i + 1
     return userhome + path[i:]
 
 
@@ -310,7 +309,7 @@
 
 def expandvars(path):
     """Expand shell variables of form $var and ${var}.  Unknown variables
-are left unchanged"""
+    are left unchanged."""
     global _varprog
     if '$' not in path:
         return path
@@ -344,9 +343,8 @@
     """Normalize path, eliminating double slashes, etc."""
     if path == '':
         return '.'
-    import string
     initial_slash = (path[0] == '/')
-    comps = string.split(path, '/')
+    comps = path.split('/')
     new_comps = []
     for comp in comps:
         if comp in ('', '.'):
@@ -357,7 +355,7 @@
         elif new_comps:
             new_comps.pop()
     comps = new_comps
-    path = string.join(comps, '/')
+    path = '/'.join(comps)
     if initial_slash:
         path = '/' + path
     return path or '.'
diff --git a/Lib/dos-8x3/sre_comp.py b/Lib/dos-8x3/sre_comp.py
index 97a57e2..dc508e5 100644
--- a/Lib/dos-8x3/sre_comp.py
+++ b/Lib/dos-8x3/sre_comp.py
@@ -222,7 +222,7 @@
 def _simple(av):
     # check if av is a "simple" operator
     lo, hi = av[2].getwidth()
-    if lo == 0:
+    if lo == 0 and hi == MAXREPEAT:
         raise error, "nothing to repeat"
     return lo == hi == 1 and av[2][0][0] != SUBPATTERN
 
diff --git a/Lib/dos-8x3/sre_cons.py b/Lib/dos-8x3/sre_cons.py
index 5a20930..ea649c0 100644
--- a/Lib/dos-8x3/sre_cons.py
+++ b/Lib/dos-8x3/sre_cons.py
@@ -9,6 +9,8 @@
 # See the sre.py file for information on usage and redistribution.
 #
 
+MAXREPEAT = 65535
+
 # should this really be here?
 
 class error(Exception):
diff --git a/Lib/dos-8x3/sre_pars.py b/Lib/dos-8x3/sre_pars.py
index f4741c9..7c36d4f 100644
--- a/Lib/dos-8x3/sre_pars.py
+++ b/Lib/dos-8x3/sre_pars.py
@@ -12,8 +12,6 @@
 
 from sre_constants import *
 
-MAXREPEAT = 65535
-
 SPECIAL_CHARS = ".\\[{()*+?^$|"
 REPEAT_CHARS = "*+?{"
 
@@ -393,6 +391,8 @@
                     # potential range
                     this = source.get()
                     if this == "]":
+                        if code1[0] is IN:
+                            code1 = code1[1][0]
                         set.append(code1)
                         set.append((LITERAL, ord("-")))
                         break
@@ -593,6 +593,11 @@
 
     # p.dump()
 
+    if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE:
+        # the VERBOSE flag was switched on inside the pattern.  to be
+        # on the safe side, we'll parse the whole thing again...
+        return parse(str, p.pattern.flags)
+
     return p
 
 def parse_template(source, pattern):
diff --git a/Lib/dos-8x3/stringio.py b/Lib/dos-8x3/stringio.py
index 02eb7c8..334bf85 100755
--- a/Lib/dos-8x3/stringio.py
+++ b/Lib/dos-8x3/stringio.py
@@ -13,6 +13,7 @@
 buf = f.read(n)     # read up to n bytes
 buf = f.readline()  # read until end of line ('\n') or EOF
 list = f.readlines()# list of f.readline() results until EOF
+f.truncate([size])  # truncate file at to at most size (default: current pos)
 f.write(buf)        # write at current position
 f.writelines(list)  # for line in list: f.write(line)
 f.getvalue()        # return whole file's contents as a string
@@ -28,6 +29,7 @@
 - There's a simple test set (see end of this file).
 """
 
+import errno
 import string
 
 class StringIO:
@@ -102,6 +104,17 @@
 				break
 			line = self.readline()
 		return lines
+	def truncate(self, size=None):
+		if self.closed:
+			raise ValueError, "I/O operation on closed file"
+		if size is None:
+			size = self.pos
+		elif size < 0:
+			raise IOError(errno.EINVAL,
+                                      "Negative size not allowed")
+		elif size < self.pos:
+			self.pos = size
+		self.buf = self.getvalue()[:size]
 	def write(self, s):
 		if self.closed:
 			raise ValueError, "I/O operation on closed file"
diff --git a/Lib/dos-8x3/test_cfg.py b/Lib/dos-8x3/test_cfg.py
new file mode 100644
index 0000000..4bdbc69
--- /dev/null
+++ b/Lib/dos-8x3/test_cfg.py
@@ -0,0 +1,141 @@
+import ConfigParser
+import StringIO
+
+def basic(src):
+    print
+    print "Testing basic accessors..."
+    cf = ConfigParser.ConfigParser()
+    sio = StringIO.StringIO(src)
+    cf.readfp(sio)
+    L = cf.sections()
+    L.sort()
+    print L
+    for s in L:
+        print "%s: %s" % (s, cf.options(s))
+
+    # The use of spaces in the section names serves as a regression test for
+    # SourceForge bug #115357.
+    # http://sourceforge.net/bugs/?func=detailbug&group_id=5470&bug_id=115357
+    print `cf.get('Foo Bar', 'foo', raw=1)`
+    print `cf.get('Spacey Bar', 'foo', raw=1)`
+    print `cf.get('Commented Bar', 'foo', raw=1)`
+
+    if '__name__' in cf.options("Foo Bar"):
+        print '__name__ "option" should not be exposed by the API!'
+    else:
+        print '__name__ "option" properly hidden by the API.'
+
+def interpolation(src):
+    print
+    print "Testing value interpolation..."
+    cf = ConfigParser.ConfigParser({"getname": "%(__name__)s"})
+    sio = StringIO.StringIO(src)
+    cf.readfp(sio)
+    print `cf.get("Foo", "getname")`
+    print `cf.get("Foo", "bar")`
+    print `cf.get("Foo", "bar9")`
+    print `cf.get("Foo", "bar10")`
+    expect_get_error(cf, ConfigParser.InterpolationDepthError, "Foo", "bar11")
+
+def parse_errors():
+    print
+    print "Testing for parsing errors..."
+    expect_parse_error(ConfigParser.ParsingError,
+                       """[Foo]\n  extra-spaces: splat\n""")
+    expect_parse_error(ConfigParser.ParsingError,
+                       """[Foo]\n  extra-spaces= splat\n""")
+    expect_parse_error(ConfigParser.ParsingError,
+                       """[Foo]\noption-without-value\n""")
+    expect_parse_error(ConfigParser.ParsingError,
+                       """[Foo]\n:value-without-option-name\n""")
+    expect_parse_error(ConfigParser.ParsingError,
+                       """[Foo]\n=value-without-option-name\n""")
+    expect_parse_error(ConfigParser.MissingSectionHeaderError,
+                       """No Section!\n""")
+
+def query_errors():
+    print
+    print "Testing query interface..."
+    cf = ConfigParser.ConfigParser()
+    print cf.sections()
+    print "Has section 'Foo'?", cf.has_section("Foo")
+    try:
+        cf.options("Foo")
+    except ConfigParser.NoSectionError, e:
+        print "Caught expected NoSectionError:", e
+    else:
+        print "Failed to catch expected NoSectionError from options()"
+    try:
+        cf.set("foo", "bar", "value")
+    except ConfigParser.NoSectionError, e:
+        print "Caught expected NoSectionError:", e
+    else:
+        print "Failed to catch expected NoSectionError from set()"
+    expect_get_error(cf, ConfigParser.NoSectionError, "foo", "bar")
+    cf.add_section("foo")
+    expect_get_error(cf, ConfigParser.NoOptionError, "foo", "bar")
+
+def weird_errors():
+    print
+    print "Testing miscellaneous error conditions..."
+    cf = ConfigParser.ConfigParser()
+    cf.add_section("Foo")
+    try:
+        cf.add_section("Foo")
+    except ConfigParser.DuplicateSectionError, e:
+        print "Caught expected DuplicateSectionError:", e
+    else:
+        print "Failed to catch expected DuplicateSectionError"
+
+def expect_get_error(cf, exctype, section, option, raw=0):
+    try:
+        cf.get(section, option, raw=raw)
+    except exctype, e:
+        print "Caught expected", exctype.__name__, ":"
+        print e
+    else:
+        print "Failed to catch expected", exctype.__name__
+
+def expect_parse_error(exctype, src):
+    cf = ConfigParser.ConfigParser()
+    sio = StringIO.StringIO(src)
+    try:
+        cf.readfp(sio)
+    except exctype, e:
+        print "Caught expected exception:", e
+    else:
+        print "Failed to catch expected", exctype.__name__
+
+basic(r"""
+[Foo Bar]
+foo=bar
+[Spacey Bar]
+foo = bar 
+[Commented Bar]
+foo: bar ; comment
+""")
+interpolation(r"""
+[Foo]
+bar=something %(with1)s interpolation (1 step)
+bar9=something %(with9)s lots of interpolation (9 steps)
+bar10=something %(with10)s lots of interpolation (10 steps)
+bar11=something %(with11)s lots of interpolation (11 steps)
+with11=%(with10)s
+with10=%(with9)s
+with9=%(with8)s
+with8=%(with7)s
+with7=%(with6)s
+with6=%(with5)s
+with5=%(with4)s
+with4=%(with3)s
+with3=%(with2)s
+with2=%(with1)s
+with1=with
+
+[Mutual Recursion]
+foo=%(bar)s
+bar=%(foo)s
+""")
+parse_errors()
+query_errors()
+weird_errors()
diff --git a/Lib/dos-8x3/test_cla.py b/Lib/dos-8x3/test_cla.py
index 1fc9971..43c1d3b 100644
--- a/Lib/dos-8x3/test_cla.py
+++ b/Lib/dos-8x3/test_cla.py
@@ -71,7 +71,7 @@
 
     def __hash__(self, *args):
         print "__hash__:", args
-        return id(self)
+        return hash(id(self))
 
     def __str__(self, *args):
         print "__str__:", args
diff --git a/Lib/dos-8x3/test_imp.py b/Lib/dos-8x3/test_imp.py
new file mode 100644
index 0000000..c7ab753
--- /dev/null
+++ b/Lib/dos-8x3/test_imp.py
@@ -0,0 +1,44 @@
+from test_support import TESTFN
+
+import os
+import random
+
+source = TESTFN + ".py"
+pyc = TESTFN + ".pyc"
+pyo = TESTFN + ".pyo"
+
+f = open(source, "w")
+print >> f, "# This will test Python's ability to import a .py file"
+a = random.randrange(1000)
+b = random.randrange(1000)
+print >> f, "a =", a
+print >> f, "b =", b
+f.close()
+
+try:
+    try:
+        mod = __import__(TESTFN)
+    except ImportError, err:
+        raise ValueError, "import from .py failed: %s" % err
+
+    if mod.a != a or mod.b != b:
+        print a, "!=", mod.a
+        print b, "!=", mod.b
+        raise ValueError, "module loaded (%s) but contents invalid" % mod
+finally:
+    os.unlink(source)
+
+try:
+    try:
+        reload(mod)
+    except ImportError, err:
+        raise ValueError, "import from .pyc/.pyo failed: %s" % err
+finally:
+    try:
+        os.unlink(pyc)
+    except os.error:
+        pass
+    try:
+        os.unlink(pyo)
+    except os.error:
+        pass
diff --git a/Lib/dos-8x3/test_lin.py b/Lib/dos-8x3/test_lin.py
index 4faaab1..7924a24 100644
--- a/Lib/dos-8x3/test_lin.py
+++ b/Lib/dos-8x3/test_lin.py
@@ -1,23 +1,89 @@
 from test_support import verbose, findfile, TestFailed, TestSkipped
-import linuxaudiodev
+
 import errno
+import fcntl
+import linuxaudiodev
 import os
+import sys
+import select
+import sunaudio
+import time
+import audioop
+
+SND_FORMAT_MULAW_8 = 1
 
 def play_sound_file(path):
     fp = open(path, 'r')
+    size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
     data = fp.read()
     fp.close()
+
+    if enc != SND_FORMAT_MULAW_8:
+        print "Expect .au file with 8-bit mu-law samples"
+        return
+
     try:
         a = linuxaudiodev.open('w')
     except linuxaudiodev.error, msg:
         if msg[0] in (errno.EACCES, errno.ENODEV):
             raise TestSkipped, msg
         raise TestFailed, msg
+
+    # convert the data to 16-bit signed
+    data = audioop.ulaw2lin(data, 2)
+
+    # set the data format
+    if sys.byteorder == 'little':
+        fmt = linuxaudiodev.AFMT_S16_LE
     else:
-        a.write(data)
-        a.close()
+        fmt = linuxaudiodev.AFMT_S16_BE
+
+    # at least check that these methods can be invoked
+    a.bufsize()
+    a.obufcount()
+    a.obuffree()
+    a.getptr()
+    a.fileno()
+
+    # set parameters based on .au file headers
+    a.setparameters(rate, 16, nchannels, fmt)
+    a.write(data)
+    a.flush()
+    a.close()
+
+def test_errors():
+    a = linuxaudiodev.open("w")
+    size = 8
+    fmt = linuxaudiodev.AFMT_U8
+    rate = 8000
+    nchannels = 1
+    try:
+        a.setparameters(-1, size, nchannels, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, -2, nchannels, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, 3, fmt)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, nchannels, 177)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
+    except ValueError, msg:
+        print msg
+    try:
+        a.setparameters(rate, 16, nchannels, fmt)
+    except ValueError, msg:
+        print msg
 
 def test():
     play_sound_file(findfile('audiotest.au'))
+    test_errors()
 
 test()
diff --git a/Lib/dos-8x3/test_min.py b/Lib/dos-8x3/test_min.py
index 8a63535..796f6a0 100644
--- a/Lib/dos-8x3/test_min.py
+++ b/Lib/dos-8x3/test_min.py
@@ -1,6 +1,7 @@
 # test for xml.dom.minidom
 
 from xml.dom.minidom import parse, Node, Document, parseString
+import xml.parsers.expat
 
 import os.path
 import sys
@@ -34,8 +35,6 @@
     confirm( dom.getElementsByTagName( "LI" )==\
             dom.documentElement.getElementsByTagName( "LI" ) )
     dom.unlink()
-    dom=None
-    confirm (len( Node.allnodes )==0)
 
 def testInsertBefore( ):
     dom=parse( tstfile )
@@ -49,9 +48,6 @@
     #confirm( docel.childNodes[0].tet=="a" )
     #confirm( docel.childNodes[2].tet=="a" )
     dom.unlink()
-    del dom
-    del docel
-    confirm( len( Node.allnodes )==0)
 
 def testAppendChild():
     dom=parse( tstfile )
@@ -59,8 +55,6 @@
     confirm( dom.documentElement.childNodes[-1].nodeName=="#comment" )
     confirm( dom.documentElement.childNodes[-1].data=="Hello" )
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testNonZero():
     dom=parse( tstfile )
@@ -68,29 +62,22 @@
     dom.appendChild( dom.createComment( "foo" ) )
     confirm( not dom.childNodes[-1].childNodes )
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testUnlink():
     dom=parse( tstfile )
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testElement():
     dom=Document()
     dom.appendChild( dom.createElement( "abc" ) )
     confirm( dom.documentElement )
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testAAA():
     dom=parseString( "<abc/>" )
     el=dom.documentElement
     el.setAttribute( "spam", "jam2" )
     dom.unlink()
-    dom=None
 
 def testAAB():
     dom=parseString( "<abc/>" )
@@ -98,7 +85,6 @@
     el.setAttribute( "spam", "jam" )
     el.setAttribute( "spam", "jam2" )
     dom.unlink()
-    dom=None
 
 def testAddAttr():
     dom=Document()
@@ -119,10 +105,7 @@
     confirm( child.attributes["def"].value=="newval" )
 
     confirm( len( child.attributes )==2 )
-
     dom.unlink()
-    dom=None
-    child=None
 
 def testDeleteAttr():
     dom=Document()
@@ -134,7 +117,6 @@
     del child.attributes["def"]
     confirm( len( child.attributes)==0 )
     dom.unlink()
-    confirm( len( Node.allnodes )==0 )
 
 def testRemoveAttr():
     dom=Document()
@@ -159,7 +141,6 @@
     confirm( len( child.attributes )==1 )
 
     dom.unlink()
-    dom=None
     
 def testRemoveAttributeNode():
     dom=Document()
@@ -171,8 +152,6 @@
     confirm( len( child.attributes )==0 )
 
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testChangeAttr():
     dom=parseString( "<abc/>" )
@@ -188,8 +167,6 @@
     el.attributes[ "spam2"]= "bam2"
     confirm( len( el.attributes )==2 )
     dom.unlink()
-    dom=None
-    confirm( len( Node.allnodes )==0 )
 
 def testGetAttrList():
     pass
@@ -235,6 +212,7 @@
     confirm( string1==string2 )
     confirm( string1.find("slash:abc" )!=-1 )
     dom.unlink()
+    confirm( len( Node.allnodes )==0 )
 
 def testAttributeRepr():
     dom=Document()
@@ -242,10 +220,17 @@
     node=el.setAttribute( "abc", "def" )
     confirm( str( node ) == repr( node ) )
     dom.unlink()
+    confirm( len( Node.allnodes )==0 )
 
 def testTextNodeRepr(): pass
 
-def testWriteXML(): pass
+def testWriteXML():
+    str = '<a b="c"/>'
+    dom = parseString(str)
+    domstr = dom.toxml()
+    dom.unlink()
+    confirm(str == domstr)
+    confirm( len( Node.allnodes )==0 )
 
 def testProcessingInstruction(): pass
 
@@ -335,6 +320,8 @@
         try:
             func()
             print "Test Succeeded", name
+            confirm(len(Node.allnodes) == 0,
+                    "assertion: len(Node.allnodes) == 0")
             if len( Node.allnodes ):
                 print "Garbage left over:"
                 if verbose:
diff --git a/Lib/dos-8x3/test_str.py b/Lib/dos-8x3/test_str.py
index 6e321e9..7f5cb80 100644
--- a/Lib/dos-8x3/test_str.py
+++ b/Lib/dos-8x3/test_str.py
@@ -1,15 +1,134 @@
-# Tests StringIO and cStringIO
+#! /usr/bin/env python
 
-import string
+# Sanity checker for time.strftime
 
-def do_test(module):
-    s = (string.letters+'\n')*5
-    f = module.StringIO(s)
-    print f.read(10)
-    print f.readline()
-    print len(f.readlines(60))
+import time, calendar, sys, string, os, re
+from test_support import verbose
 
-# Don't bother testing cStringIO without
-import StringIO, cStringIO
-do_test(StringIO)
-do_test(cStringIO)
+def main():
+    global verbose
+    now = time.time()
+    strftest(now)
+    verbose = 0
+    # Try a bunch of dates and times,  chosen to vary through time of
+    # day and daylight saving time
+    for j in range(-5, 5):
+        for i in range(25):
+            strftest(now + (i + j*100)*23*3603)
+
+def strftest(now):
+    if verbose:
+        print "strftime test for", time.ctime(now)
+    nowsecs = str(long(now))[:-1]
+    gmt = time.gmtime(now)
+    now = time.localtime(now)
+
+    if now[3] < 12: ampm='(AM|am)'
+    else: ampm='(PM|pm)'
+
+    jan1 = time.localtime(time.mktime((now[0], 1, 1) + (0,)*6))
+
+    try:
+        if now[8]: tz = time.tzname[1]
+        else: tz = time.tzname[0]
+    except AttributeError:
+        tz = ''
+
+    if now[3] > 12: clock12 = now[3] - 12
+    elif now[3] > 0: clock12 = now[3]
+    else: clock12 = 12
+
+    expectations = (
+        ('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'),
+        ('%A', calendar.day_name[now[6]], 'full weekday name'),
+        ('%b', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%B', calendar.month_name[now[1]], 'full month name'),
+        # %c see below
+        ('%d', '%02d' % now[2], 'day of month as number (00-31)'),
+        ('%H', '%02d' % now[3], 'hour (00-23)'),
+        ('%I', '%02d' % clock12, 'hour (01-12)'),
+        ('%j', '%03d' % now[7], 'julian day (001-366)'),
+        ('%m', '%02d' % now[1], 'month as number (01-12)'),
+        ('%M', '%02d' % now[4], 'minute, (00-59)'),
+        ('%p', ampm, 'AM or PM as appropriate'),
+        ('%S', '%02d' % now[5], 'seconds of current time (00-60)'),
+        ('%U', '%02d' % ((now[7] + jan1[6])/7),
+         'week number of the year (Sun 1st)'),
+        ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'),
+        ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)/7),
+         'week number of the year (Mon 1st)'),
+        # %x see below
+        ('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%y', '%02d' % (now[0]%100), 'year without century'),
+        ('%Y', '%d' % now[0], 'year with century'),
+        # %Z see below
+        ('%%', '%', 'single percent sign'),
+        )
+
+    nonstandard_expectations = (
+        # These are standard but don't have predictable output
+        ('%c', fixasctime(time.asctime(now)), 'near-asctime() format'),
+        ('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)),
+         '%m/%d/%y %H:%M:%S'),
+        ('%Z', '%s' % tz, 'time zone name'),
+
+        # These are some platform specific extensions
+        ('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'),
+        ('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'),
+        ('%h', calendar.month_abbr[now[1]], 'abbreviated month name'),
+        ('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'),
+        ('%n', '\n', 'newline character'),
+        ('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm),
+         '%I:%M:%S %p'),
+        ('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'),
+        ('%s', nowsecs, 'seconds since the Epoch in UCT'),
+        ('%t', '\t', 'tab character'),
+        ('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
+        ('%3y', '%03d' % (now[0]%100),
+         'year without century rendered using fieldwidth'),
+        )
+
+    if verbose:
+        print "Strftime test, platform: %s, Python version: %s" % \
+              (sys.platform, string.split(sys.version)[0])
+
+    for e in expectations:
+        try:
+            result = time.strftime(e[0], now)
+        except ValueError, error:
+            print "Standard '%s' format gave error:" % e[0], error
+            continue
+        if re.match(e[1], result): continue
+        if not result or result[0] == '%':
+            print "Does not support standard '%s' format (%s)" % (e[0], e[2])
+        else:
+            print "Conflict for %s (%s):" % (e[0], e[2])
+            print "  Expected %s, but got %s" % (e[1], result)
+
+    for e in nonstandard_expectations:
+        try:
+            result = time.strftime(e[0], now)
+        except ValueError, result:
+            if verbose:
+                print "Error for nonstandard '%s' format (%s): %s" % \
+                      (e[0], e[2], str(result))
+            continue
+        if re.match(e[1], result):
+            if verbose:
+                print "Supports nonstandard '%s' format (%s)" % (e[0], e[2])
+        elif not result or result[0] == '%':
+            if verbose:
+                print "Does not appear to support '%s' format (%s)" % (e[0],
+                                                                       e[2])
+        else:
+            if verbose:
+                print "Conflict for nonstandard '%s' format (%s):" % (e[0],
+                                                                      e[2])
+                print "  Expected %s, but got %s" % (e[1], result)
+
+def fixasctime(s):
+    if s[8] == ' ':
+        s = s[:8] + '0' + s[9:]
+    return s
+
+main()
diff --git a/Lib/dos-8x3/test_uni.py b/Lib/dos-8x3/test_uni.py
index 8479c20..0c44fbf 100644
--- a/Lib/dos-8x3/test_uni.py
+++ b/Lib/dos-8x3/test_uni.py
@@ -341,6 +341,7 @@
 assert '...%(foo)s...' % {u'foo':u"abc",'def':123} ==  u'...abc...'
 assert '...%(foo)s...' % {u'foo':u"abc",u'def':123} == u'...abc...'
 assert '...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...1...2...3...abc...'
+assert '...%%...%%s...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...%...%s...1...2...3...abc...'
 assert '...%s...' % u"abc" == u'...abc...'
 print 'done.'
 
diff --git a/Lib/dos-8x3/test_url.py b/Lib/dos-8x3/test_url.py
index 484acea..e69de29 100644
--- a/Lib/dos-8x3/test_url.py
+++ b/Lib/dos-8x3/test_url.py
@@ -1,32 +0,0 @@
-# Minimal test of the quote function
-import urllib
-
-chars = 'abcdefghijklmnopqrstuvwxyz'\
-        '\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356' \
-        '\357\360\361\362\363\364\365\366\370\371\372\373\374\375\376\377' \
-        'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
-        '\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317' \
-        '\320\321\322\323\324\325\326\330\331\332\333\334\335\336'
-
-expected = 'abcdefghijklmnopqrstuvwxyz%df%e0%e1%e2%e3%e4%e5%e6%e7%e8%e9%ea%eb%ec%ed%ee%ef%f0%f1%f2%f3%f4%f5%f6%f8%f9%fa%fb%fc%fd%fe%ffABCDEFGHIJKLMNOPQRSTUVWXYZ%c0%c1%c2%c3%c4%c5%c6%c7%c8%c9%ca%cb%cc%cd%ce%cf%d0%d1%d2%d3%d4%d5%d6%d8%d9%da%db%dc%dd%de'
-
-test = urllib.quote(chars)
-assert test == expected, "urllib.quote problem"
-test2 = urllib.unquote(expected)
-assert test2 == chars
-
-in1 = "abc/def"
-out1_1 = "abc/def"
-out1_2 = "abc%2fdef"
-
-assert urllib.quote(in1) == out1_1, "urllib.quote problem"
-assert urllib.quote(in1, '') == out1_2, "urllib.quote problem"
-
-in2 = "abc?def"
-out2_1 = "abc%3fdef"
-out2_2 = "abc?def"
-
-assert urllib.quote(in2) == out2_1, "urllib.quote problem"
-assert urllib.quote(in2, '?') == out2_2, "urllib.quote problem"
-
-
diff --git a/Lib/dos-8x3/test_wav.py b/Lib/dos-8x3/test_wav.py
new file mode 100644
index 0000000..a7a5e24
--- /dev/null
+++ b/Lib/dos-8x3/test_wav.py
@@ -0,0 +1,34 @@
+from test_support import TestFailed
+import os, tempfile
+import wave
+
+def check(t, msg=None):
+    if not t:
+        raise TestFailed, msg
+
+nchannels = 2
+sampwidth = 2
+framerate = 8000
+nframes = 100
+
+testfile = tempfile.mktemp()
+
+f = wave.open(testfile, 'w')
+f.setnchannels(nchannels)
+f.setsampwidth(sampwidth)
+f.setframerate(framerate)
+f.setnframes(nframes)
+output = '\0' * nframes * nchannels * sampwidth
+f.writeframes(output)
+f.close()
+
+f = wave.open(testfile, 'r')
+check(nchannels == f.getnchannels(), "nchannels")
+check(sampwidth == f.getsampwidth(), "sampwidth")
+check(framerate == f.getframerate(), "framerate")
+check(nframes == f.getnframes(), "nframes")
+input = f.readframes(nframes)
+check(input == output, "data")
+f.close()
+
+os.remove(testfile)
diff --git a/Lib/dos-8x3/test_win.py b/Lib/dos-8x3/test_win.py
index 18ce7a7..7b4fa15 100644
--- a/Lib/dos-8x3/test_win.py
+++ b/Lib/dos-8x3/test_win.py
@@ -1,147 +1,7 @@
-# Test the windows specific win32reg module.
-# Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
+# Ridiculously simple test of the winsound module for Windows.
 
-from _winreg import *
-import os, sys
-
-test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
-
-test_data = [
-    ("Int Value",     45,                                      REG_DWORD),
-    ("String Val",    "A string value",                        REG_SZ,),
-    (u"Unicode Val",  u"A Unicode value",                      REG_SZ,),
-    ("StringExpand",  "The path is %path%",                    REG_EXPAND_SZ),
-    ("UnicodeExpand", u"The path is %path%",                   REG_EXPAND_SZ),
-    ("Multi-string",  ["Lots", "of", "string", "values"],      REG_MULTI_SZ),
-    ("Multi-unicode", [u"Lots", u"of", u"unicode", u"values"], REG_MULTI_SZ),
-    ("Multi-mixed",   [u"Unicode", u"and", "string", "values"],REG_MULTI_SZ),
-    ("Raw Data",      ("binary"+chr(0)+"data"),                REG_BINARY),
-]
-
-def WriteTestData(root_key):
-    # Set the default value for this key.
-    SetValue(root_key, test_key_name, REG_SZ, "Default value")
-    key = CreateKey(root_key, test_key_name)
-    # Create a sub-key
-    sub_key = CreateKey(key, "sub_key")
-    # Give the sub-key some named values
-
-    for value_name, value_data, value_type in test_data:
-        SetValueEx(sub_key, value_name, 0, value_type, value_data)
-
-    # Check we wrote as many items as we thought.
-    nkeys, nvalues, since_mod = QueryInfoKey(key)
-    assert nkeys==1, "Not the correct number of sub keys"
-    assert nvalues==1, "Not the correct number of values"
-    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
-    assert nkeys==0, "Not the correct number of sub keys"
-    assert nvalues==len(test_data), "Not the correct number of values"
-    # Close this key this way...
-    # (but before we do, copy the key as an integer - this allows
-    # us to test that the key really gets closed).
-    int_sub_key = int(sub_key)
-    CloseKey(sub_key)
-    try:
-        QueryInfoKey(int_sub_key)
-        raise RuntimeError, "It appears the CloseKey() function does not close the actual key!"
-    except EnvironmentError:
-        pass
-    # ... and close that key that way :-)
-    int_key = int(key)
-    key.Close()
-    try:
-        QueryInfoKey(int_key)
-        raise RuntimeError, "It appears the key.Close() function does not close the actual key!"
-    except EnvironmentError:
-        pass
-
-def ReadTestData(root_key):
-    # Check we can get default value for this key.
-    val = QueryValue(root_key, test_key_name)
-    assert val=="Default value", "Registry didn't give back the correct value"
-
-    key = OpenKey(root_key, test_key_name)
-    # Read the sub-keys
-    sub_key = OpenKey(key, "sub_key")
-    # Check I can enumerate over the values.
-    index = 0
-    while 1:
-        try:
-            data = EnumValue(sub_key, index)
-        except EnvironmentError:
-            break
-        assert data in test_data, "Didn't read back the correct test data"
-        index = index + 1
-    assert index==len(test_data), "Didn't read the correct number of items"
-    # Check I can directly access each item
-    for value_name, value_data, value_type in test_data:
-        read_val, read_typ = QueryValueEx(sub_key, value_name)
-        assert read_val==value_data and read_typ == value_type, \
-               "Could not directly read the value"
-    sub_key.Close()
-    # Enumerate our main key.
-    read_val = EnumKey(key, 0)
-    assert read_val == "sub_key", "Read subkey value wrong"
-    try:
-        EnumKey(key, 1)
-        assert 0, "Was able to get a second key when I only have one!"
-    except EnvironmentError:
-        pass
-
-    key.Close()
-
-def DeleteTestData(root_key):
-    key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
-    sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
-    # It is not necessary to delete the values before deleting
-    # the key (although subkeys must not exist).  We delete them
-    # manually just to prove we can :-)
-    for value_name, value_data, value_type in test_data:
-        DeleteValue(sub_key, value_name)
-
-    nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
-    assert nkeys==0 and nvalues==0, "subkey not empty before delete"
-    sub_key.Close()
-    DeleteKey(key, "sub_key")
-
-    try:
-        # Shouldnt be able to delete it twice!
-        DeleteKey(key, "sub_key")
-        assert 0, "Deleting the key twice succeeded"
-    except EnvironmentError:
-        pass
-    key.Close()
-    DeleteKey(root_key, test_key_name)
-    # Opening should now fail!
-    try:
-        key = OpenKey(root_key, test_key_name)
-        assert 0, "Could open the non-existent key"
-    except WindowsError: # Use this error name this time
-        pass
-
-def TestAll(root_key):
-    WriteTestData(root_key)
-    ReadTestData(root_key)
-    DeleteTestData(root_key)
-
-# Test on my local machine.
-TestAll(HKEY_CURRENT_USER)
-print "Local registry tests worked"
-try:
-    remote_name = sys.argv[sys.argv.index("--remote")+1]
-except (IndexError, ValueError):
-    remote_name = None
-
-if remote_name is not None:
-    try:
-        remote_key = ConnectRegistry(remote_name, HKEY_CURRENT_USER)
-    except EnvironmentError, exc:
-        print "Could not connect to the remote machine -", exc.strerror
-        remote_key = None
-    if remote_key is not None:
-        TestAll(remote_key)
-        print "Remote registry tests worked"
-else:
-    print "Remote registry calls can be tested using",
-    print "'test_winreg.py --remote \\\\machine_name'"
+import winsound
+for i in range(100, 2000, 100):
+    winsound.Beep(i, 75)
+print "Hopefully you heard some sounds increasing in frequency!"
 
diff --git a/Lib/dos-8x3/userlist.py b/Lib/dos-8x3/userlist.py
index aab5119..e79faea 100755
--- a/Lib/dos-8x3/userlist.py
+++ b/Lib/dos-8x3/userlist.py
@@ -24,9 +24,7 @@
     def __delitem__(self, i): del self.data[i]
     def __getslice__(self, i, j):
         i = max(i, 0); j = max(j, 0)
-        userlist = self.__class__()
-        userlist.data[:] = self.data[i:j]
-        return userlist
+        return self.__class__(self.data[i:j])
     def __setslice__(self, i, j, other):
         i = max(i, 0); j = max(j, 0)
         if isinstance(other, UserList):
diff --git a/Lib/dos-8x3/webbrows.py b/Lib/dos-8x3/webbrows.py
index a8b0e8b..da70e3b 100644
--- a/Lib/dos-8x3/webbrows.py
+++ b/Lib/dos-8x3/webbrows.py
@@ -196,9 +196,7 @@
     register("windows-default", WindowsDefault)
     DEFAULT_BROWSER = "windows-default"
 elif os.environ.get("DISPLAY"):
-    if os.environ.get("KDEDIR"):
-        DEFAULT_BROWSER = "kfm"
-    elif _iscommand("netscape"):
+    if _iscommand("netscape"):
         DEFAULT_BROWSER = "netscape"
 
 # If the $BROWSER environment variable is set and true, let that be