The usual
diff --git a/Lib/dos-8x3/basehttp.py b/Lib/dos-8x3/basehttp.py
index 7c8975d..4c9645d 100755
--- a/Lib/dos-8x3/basehttp.py
+++ b/Lib/dos-8x3/basehttp.py
@@ -252,7 +252,7 @@
         self.headers = self.MessageClass(self.rfile, 0)
         mname = 'do_' + command
         if not hasattr(self, mname):
-            self.send_error(501, "Unsupported method (%s)" % `mname`)
+            self.send_error(501, "Unsupported method (%s)" % `command`)
             return
         method = getattr(self, mname)
         method()
diff --git a/Lib/dos-8x3/compilea.py b/Lib/dos-8x3/compilea.py
index 69a59b3..e56c8b2 100755
--- a/Lib/dos-8x3/compilea.py
+++ b/Lib/dos-8x3/compilea.py
@@ -36,6 +36,7 @@
         print "Can't list", dir
         names = []
     names.sort()
+    success = 1
     for name in names:
         fullname = os.path.join(dir, name)
         if ddir:
@@ -61,11 +62,13 @@
                     else: exc_type_name = sys.exc_type.__name__
                     print 'Sorry:', exc_type_name + ':',
                     print sys.exc_value
+                    success = 0
         elif maxlevels > 0 and \
              name != os.curdir and name != os.pardir and \
              os.path.isdir(fullname) and \
              not os.path.islink(fullname):
             compile_dir(fullname, maxlevels - 1, dfile, force)
+    return success
 
 def compile_path(skip_curdir=1, maxlevels=0, force=0):
     """Byte-compile all module on sys.path.
@@ -77,11 +80,13 @@
     force: as for compile_dir() (default 0)
 
     """
+    success = 1
     for dir in sys.path:
         if (not dir or dir == os.curdir) and skip_curdir:
             print 'Skipping current directory'
         else:
-            compile_dir(dir, maxlevels, None, force)
+            success = success and compile_dir(dir, maxlevels, None, force)
+    return success
 
 def main():
     """Script main program."""
@@ -107,14 +112,17 @@
         if len(args) != 1:
             print "-d destdir require exactly one directory argument"
             sys.exit(2)
+    success = 1
     try:
         if args:
             for dir in args:
-                compile_dir(dir, maxlevels, ddir, force)
+                success = success and compile_dir(dir, maxlevels, ddir, force)
         else:
-            compile_path()
+            success = compile_path()
     except KeyboardInterrupt:
         print "\n[interrupt]"
+        success = 0
+    return success
 
 if __name__ == '__main__':
-    main()
+    sys.exit(not main())
diff --git a/Lib/dos-8x3/exceptio.py b/Lib/dos-8x3/exceptio.py
index 2963c04..e943f7b 100644
--- a/Lib/dos-8x3/exceptio.py
+++ b/Lib/dos-8x3/exceptio.py
@@ -11,10 +11,11 @@
 tricky uses of IOError may break, but the most common uses should work.
 
 Here is a rundown of the class hierarchy.  You can change this by editing this
-file, but it isn't recommended.  The class names described here are expected
-to be found by the bltinmodule.c file.  If you add classes here, you must
-modify bltinmodule.c or the exceptions won't be available in the __builtin__
-module, nor will they be accessible from C.
+file, but it isn't recommended because the old string based exceptions won't
+be kept in sync.  The class names described here are expected to be found by
+the bltinmodule.c file.  If you add classes here, you must modify
+bltinmodule.c or the exceptions won't be available in the __builtin__ module,
+nor will they be accessible from C.
 
 The classes with a `*' are new since Python 1.5.  They are defined as tuples
 containing the derived exceptions when string-based exceptions are used.  If
@@ -23,9 +24,9 @@
 
 Exception(*)
  |
+ +-- SystemExit
  +-- StandardError(*)
       |
-      +-- SystemExit
       +-- KeyboardInterrupt
       +-- ImportError
       +-- EnvironmentError(*)
diff --git a/Lib/dos-8x3/mimetype.py b/Lib/dos-8x3/mimetype.py
index 3d6510e..f15160f 100644
--- a/Lib/dos-8x3/mimetype.py
+++ b/Lib/dos-8x3/mimetype.py
@@ -201,6 +201,7 @@
     '.qt': 'video/quicktime',
     '.ras': 'image/x-cmu-raster',
     '.rgb': 'image/x-rgb',
+    '.rdf': 'application/xml',
     '.roff': 'application/x-troff',
     '.rtf': 'application/rtf',
     '.rtx': 'text/richtext',
@@ -228,6 +229,7 @@
     '.wav': 'audio/x-wav',
     '.xbm': 'image/x-xbitmap',
     '.xml': 'text/xml',
+    '.xsl': 'application/xml',
     '.xpm': 'image/x-xpixmap',
     '.xwd': 'image/x-xwindowdump',
     '.zip': 'application/zip',
diff --git a/Lib/dos-8x3/nturl2pa.py b/Lib/dos-8x3/nturl2pa.py
index a25dc2a..8c02049 100755
--- a/Lib/dos-8x3/nturl2pa.py
+++ b/Lib/dos-8x3/nturl2pa.py
@@ -10,21 +10,27 @@
 
 		C:\foo\bar\spam.foo
 	"""
-	import string
+	import string, urllib
 	if not '|' in url:
 	    # No drive specifier, just convert slashes
-	    components = string.splitfields(url, '/')
-	    return string.joinfields(components, '\\')
-	comp = string.splitfields(url, '|')
+	    if url[:4] == '////':
+	        # path is something like ////host/path/on/remote/host
+	        # convert this to \\host\path\on\remote\host
+	        # (notice halving of slashes at the start of the path)
+	        url = url[2:]
+	    components = string.split(url, '/')
+	    # make sure not to convert quoted slashes :-)
+	    return urllib.unquote(string.join(components, '\\'))
+	comp = string.split(url, '|')
 	if len(comp) != 2 or comp[0][-1] not in string.letters:
 		error = 'Bad URL: ' + url
 		raise IOError, error
 	drive = string.upper(comp[0][-1])
-	components = string.splitfields(comp[1], '/')
+	components = string.split(comp[1], '/')
 	path = drive + ':'
 	for  comp in components:
 		if comp:
-			path = path + '\\' + comp
+			path = path + '\\' + urllib.unquote(comp)
 	return path
 
 def pathname2url(p):
@@ -37,20 +43,25 @@
 		///C|/foo/bar/spam.foo
 	"""
 
-	import string
+	import string, urllib
 	if not ':' in p:
-	    # No drive specifier, just convert slashes
-	    components = string.splitfields(p, '\\')
-	    return string.joinfields(components, '/')
-	comp = string.splitfields(p, ':')
+	    # No drive specifier, just convert slashes and quote the name
+	    if p[:2] == '\\\\':
+	        # path is something like \\host\path\on\remote\host
+	        # convert this to ////host/path/on/remote/host
+	        # (notice doubling of slashes at the start of the path)
+	        p = '\\\\' + p
+	    components = string.split(p, '\\')
+	    return urllib.quote(string.join(components, '/'))
+	comp = string.split(p, ':')
 	if len(comp) != 2 or len(comp[0]) > 1:
 		error = 'Bad path: ' + p
 		raise IOError, error
 
-	drive = string.upper(comp[0])
-	components = string.splitfields(comp[1], '\\')
+	drive = urllib.quote(string.upper(comp[0]))
+	components = string.split(comp[1], '\\')
 	path = '///' + drive + '|'
 	for comp in components:
 		if comp:
-			path = path + '/' + comp
+			path = path + '/' + urllib.quote(comp)
 	return path
diff --git a/Lib/dos-8x3/posixfil.py b/Lib/dos-8x3/posixfil.py
index d3aeac0..2cd4168 100755
--- a/Lib/dos-8x3/posixfil.py
+++ b/Lib/dos-8x3/posixfil.py
@@ -177,7 +177,9 @@
         # Hack by davem@magnet.com to get locking to go on freebsd;
         # additions for AIX by Vladimir.Marangozov@imag.fr
         import sys, os
-        if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
+        if sys.platform in ('netbsd1',
+                            'freebsd2', 'freebsd3',
+                            'bsdos2', 'bsdos3', 'bsdos4'):
             flock = struct.pack('lxxxxlxxxxlhh', \
                   l_start, l_len, os.getpid(), l_type, l_whence) 
         elif sys.platform in ['aix3', 'aix4']:
@@ -190,7 +192,9 @@
         flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
 
         if '?' in how:
-            if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
+            if sys.platform in ('netbsd1',
+                                'freebsd2', 'freebsd3',
+                                'bsdos2', 'bsdos3', 'bsdos4'):
                 l_start, l_len, l_pid, l_type, l_whence = \
                     struct.unpack('lxxxxlxxxxlhh', flock)
             elif sys.platform in ['aix3', 'aix4']:
diff --git a/Lib/dos-8x3/test_bsd.py b/Lib/dos-8x3/test_bsd.py
index 1188e06..e5780ea 100644
--- a/Lib/dos-8x3/test_bsd.py
+++ b/Lib/dos-8x3/test_bsd.py
@@ -2,6 +2,8 @@
 """Test script for the bsddb C module
    Roger E. Masse
 """
+
+import os
 import bsddb
 import tempfile
 from test_support import verbose
@@ -56,6 +58,10 @@
             print word
 
     f.close()
+    try:
+        os.remove(fname)
+    except os.error:
+        pass
 
 types = [(bsddb.btopen, 'BTree'),
          (bsddb.hashopen, 'Hash Table'),
@@ -66,4 +72,3 @@
 
 for type in types:
     test(type[0], type[1])
-
diff --git a/Lib/dos-8x3/test_cpi.py b/Lib/dos-8x3/test_cpi.py
new file mode 100644
index 0000000..9088eb7
--- /dev/null
+++ b/Lib/dos-8x3/test_cpi.py
@@ -0,0 +1,96 @@
+# Test the cPickle module
+
+DATA = """(lp0
+I0
+aL1L
+aF2.0
+ac__builtin__
+complex
+p1
+(F3.0
+F0.0
+tp2
+Rp3
+a(S'abc'
+p4
+g4
+(i__main__
+C
+p5
+(dp6
+S'foo'
+p7
+I1
+sS'bar'
+p8
+I2
+sbg5
+tp9
+ag9
+aI5
+a.
+"""
+
+BINDATA = ']q\000(K\000L1L\012G@\000\000\000\000\000\000\000c__builtin__\012complex\012q\001(G@\010\000\000\000\000\000\000G\000\000\000\000\000\000\000\000tq\002Rq\003(U\003abcq\004h\004(c__main__\012C\012q\005oq\006}q\007(U\003fooq\010K\001U\003barq\011K\002ubh\006tq\012h\012K\005e.'
+
+import cPickle
+
+class C:
+    def __cmp__(self, other):
+        return cmp(self.__dict__, other.__dict__)
+
+import __main__
+__main__.C = C
+
+def dotest():
+    c = C()
+    c.foo = 1
+    c.bar = 2
+    x = [0, 1L, 2.0, 3.0+0j]
+    y = ('abc', 'abc', c, c)
+    x.append(y)
+    x.append(y)
+    x.append(5)
+    print "dumps()"
+    s = cPickle.dumps(x)
+    print "loads()"
+    x2 = cPickle.loads(s)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "loads() DATA"
+    x2 = cPickle.loads(DATA)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "dumps() binary"
+    s = cPickle.dumps(x, 1)
+    print "loads() binary"
+    x2 = cPickle.loads(s)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "loads() BINDATA"
+    x2 = cPickle.loads(BINDATA)
+    if x2 == x: print "ok"
+    else: print "bad"
+
+    # Test protection against closed files
+    import tempfile, os
+    fn = tempfile.mktemp()
+    f = open(fn, "w")
+    f.close()
+    try:
+        cPickle.dump(123, f)
+    except IOError:
+        pass
+    else:
+        print "dump to closed file should raise IOError"
+    f = open(fn, "r")
+    f.close()
+    try:
+        cPickle.load(f)
+    except IOError:
+        pass
+    else:
+        print "load from closed file should raise IOError"
+    os.remove(fn)
+
+dotest()
diff --git a/Lib/dos-8x3/test_fcn.py b/Lib/dos-8x3/test_fcn.py
index f2d4537..10144c3 100644
--- a/Lib/dos-8x3/test_fcn.py
+++ b/Lib/dos-8x3/test_fcn.py
@@ -16,7 +16,9 @@
 if verbose:
     print 'Status from fnctl with O_NONBLOCK: ', rv
     
-if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3', 'bsdos2', 'bsdos3'):
+if sys.platform in ('netbsd1',
+                    'freebsd2', 'freebsd3',
+                    'bsdos2', 'bsdos3', 'bsdos4'):
     lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
 elif sys.platform in ['aix3', 'aix4']:
     lockdata = struct.pack('hhlllii', FCNTL.F_WRLCK, 0, 0, 0, 0, 0, 0)
diff --git a/Lib/dos-8x3/test_gzi.py b/Lib/dos-8x3/test_gzi.py
new file mode 100644
index 0000000..3ea2ba9
--- /dev/null
+++ b/Lib/dos-8x3/test_gzi.py
@@ -0,0 +1,30 @@
+
+import sys, os
+import gzip, tempfile
+
+filename = tempfile.mktemp()
+
+data1 = """  int length=DEFAULTALLOC, err = Z_OK;
+  PyObject *RetVal;
+  int flushmode = Z_FINISH;
+  unsigned long start_total_out;
+
+"""
+
+data2 = """/* zlibmodule.c -- gzip-compatible data compression */
+/* See http://www.cdrom.com/pub/infozip/zlib/ */
+/* See http://www.winimage.com/zLibDll for Windows */
+"""
+
+f = gzip.GzipFile(filename, 'wb') ; f.write(data1) ; f.close()
+
+f = gzip.GzipFile(filename, 'rb') ; d = f.read() ; f.close()
+assert d == data1
+
+# Append to the previous file
+f = gzip.GzipFile(filename, 'ab') ; f.write(data2) ; f.close()
+
+f = gzip.GzipFile(filename, 'rb') ; d = f.read() ; f.close()
+assert d == data1+data2
+
+os.unlink( filename )
diff --git a/Lib/dos-8x3/test_ntp.py b/Lib/dos-8x3/test_ntp.py
index 9c79865..1f824a5 100644
--- a/Lib/dos-8x3/test_ntp.py
+++ b/Lib/dos-8x3/test_ntp.py
@@ -16,18 +16,18 @@
 		errors = errors + 1
 
 tester('ntpath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar'))
-tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint', '\\foo\\bar'))
+tester('ntpath.splitunc("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint', '\\foo\\bar'))
 tester('ntpath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar'))
-tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")', ('//conky/mountpoint', '/foo/bar'))
+tester('ntpath.splitunc("//conky/mountpoint/foo/bar")', ('//conky/mountpoint', '/foo/bar'))
 
 tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
 tester('ntpath.split("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint\\foo', 'bar'))
 
 tester('ntpath.split("c:\\")', ('c:\\', ''))
-tester('ntpath.split("\\\\conky\\mountpoint\\")', ('\\\\conky\\mountpoint\\', ''))
+tester('ntpath.split("\\\\conky\\mountpoint\\")', ('\\\\conky\\mountpoint', ''))
 
 tester('ntpath.split("c:/")', ('c:/', ''))
-tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint/', ''))
+tester('ntpath.split("//conky/mountpoint/")', ('//conky/mountpoint', ''))
 
 tester('ntpath.isabs("c:\\")', 1)
 tester('ntpath.isabs("\\\\conky\\mountpoint\\")', 1)
diff --git a/Lib/dos-8x3/test_pic.py b/Lib/dos-8x3/test_pic.py
new file mode 100644
index 0000000..8fb534d
--- /dev/null
+++ b/Lib/dos-8x3/test_pic.py
@@ -0,0 +1,75 @@
+# Test the pickle module
+
+DATA = """(lp0
+I0
+aL1L
+aF2.0
+ac__builtin__
+complex
+p1
+(F3.0
+F0.0
+tp2
+Rp3
+a(S'abc'
+p4
+g4
+(i__main__
+C
+p5
+(dp6
+S'foo'
+p7
+I1
+sS'bar'
+p8
+I2
+sbg5
+tp9
+ag9
+aI5
+a.
+"""
+
+BINDATA = ']q\000(K\000L1L\012G@\000\000\000\000\000\000\000c__builtin__\012complex\012q\001(G@\010\000\000\000\000\000\000G\000\000\000\000\000\000\000\000tq\002Rq\003(U\003abcq\004h\004(c__main__\012C\012q\005oq\006}q\007(U\003fooq\010K\001U\003barq\011K\002ubh\006tq\012h\012K\005e.'
+
+import pickle
+
+class C:
+    def __cmp__(self, other):
+        return cmp(self.__dict__, other.__dict__)
+
+import __main__
+__main__.C = C
+
+def dotest():
+    c = C()
+    c.foo = 1
+    c.bar = 2
+    x = [0, 1L, 2.0, 3.0+0j]
+    y = ('abc', 'abc', c, c)
+    x.append(y)
+    x.append(y)
+    x.append(5)
+    print "dumps()"
+    s = pickle.dumps(x)
+    print "loads()"
+    x2 = pickle.loads(s)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "loads() DATA"
+    x2 = pickle.loads(DATA)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "dumps() binary"
+    s = pickle.dumps(x, 1)
+    print "loads() binary"
+    x2 = pickle.loads(s)
+    if x2 == x: print "ok"
+    else: print "bad"
+    print "loads() BINDATA"
+    x2 = pickle.loads(BINDATA)
+    if x2 == x: print "ok"
+    else: print "bad"
+
+dotest()
diff --git a/Lib/dos-8x3/test_pop.py b/Lib/dos-8x3/test_pop.py
new file mode 100644
index 0000000..be79f3c
--- /dev/null
+++ b/Lib/dos-8x3/test_pop.py
@@ -0,0 +1,17 @@
+#! /usr/bin/env python
+"""Test script for popen2.py
+   Christian Tismer
+"""
+
+# popen2 contains its own testing routine
+# which is especially useful to see if open files
+# like stdin can be read successfully by a forked 
+# subprocess.
+
+def main():
+    from os import fork # skips test through ImportError
+    import popen2
+    popen2._test()
+
+main()
+
diff --git a/Lib/dos-8x3/test_use.py b/Lib/dos-8x3/test_use.py
new file mode 100644
index 0000000..63632f7
--- /dev/null
+++ b/Lib/dos-8x3/test_use.py
@@ -0,0 +1,101 @@
+# Check every path through every method of UserDict
+
+from UserDict import UserDict
+
+d0 = {}
+d1 = {"one": 1}
+d2 = {"one": 1, "two": 2}
+
+# Test constructors
+
+u = UserDict()
+u0 = UserDict(d0)
+u1 = UserDict(d1)
+u2 = UserDict(d2)
+
+uu = UserDict(u)
+uu0 = UserDict(u0)
+uu1 = UserDict(u1)
+uu2 = UserDict(u2)
+
+# Test __repr__
+
+assert str(u0) == str(d0)
+assert repr(u1) == repr(d1)
+assert `u2` == `d2`
+
+# Test __cmp__ and __len__
+
+all = [d0, d1, d2, u, u0, u1, u2, uu, uu0, uu1, uu2]
+for a in all:
+    for b in all:
+        assert cmp(a, b) == cmp(len(a), len(b))
+
+# Test __getitem__
+
+assert u2["one"] == 1
+try:
+    u1["two"]
+except KeyError:
+    pass
+else:
+    assert 0, "u1['two'] shouldn't exist"
+
+# Test __setitem__
+
+u3 = UserDict(u2)
+u3["two"] = 2
+u3["three"] = 3
+
+# Test __delitem__
+
+del u3["three"]
+try:
+    del u3["three"]
+except KeyError:
+    pass
+else:
+    assert 0, "u3['three'] shouldn't exist"
+
+# Test clear
+
+u3.clear()
+assert u3 == {}
+
+# Test copy()
+
+u2a = u2.copy()
+assert u2a == u2
+
+class MyUserDict(UserDict):
+    def display(self): print self
+
+m2 = MyUserDict(u2)
+m2a = m2.copy()
+assert m2a == m2
+
+# Test keys, items, values
+
+assert u2.keys() == d2.keys()
+assert u2.items() == d2.items()
+assert u2.values() == d2.values()
+
+# Test has_key
+
+for i in u2.keys():
+    assert u2.has_key(i) == 1
+    assert u1.has_key(i) == d1.has_key(i)
+    assert u0.has_key(i) == d0.has_key(i)
+
+# Test update
+
+t = UserDict()
+t.update(u2)
+assert t == u2
+
+# Test get
+
+for i in u2.keys():
+    assert u2.get(i) == u2[i]
+    assert u1.get(i) == d1.get(i)
+    assert u0.get(i) == d0.get(i)
diff --git a/Lib/dos-8x3/test_zli.py b/Lib/dos-8x3/test_zli.py
index 047e985..719b0e7 100644
--- a/Lib/dos-8x3/test_zli.py
+++ b/Lib/dos-8x3/test_zli.py
@@ -76,6 +76,19 @@
 else:
     print "decompressobj with init options succeeded"
 
+# Test flush() with the various options, using all the different levels
+# in order to provide more variations.
+for sync in [zlib.Z_NO_FLUSH, zlib.Z_SYNC_FLUSH, zlib.Z_FULL_FLUSH]:
+    for level in range(10):
+	obj = zlib.compressobj( level )
+    	d = obj.compress( buf[:3000] )
+	d = d + obj.flush( sync )
+	d = d + obj.compress( buf[3000:] )
+	d = d + obj.flush()
+	if zlib.decompress(d) != buf:
+	    print "Decompress failed: flush mode=%i, level=%i" % (sync,level)
+	del obj
+
 def ignore():
     """An empty function with a big string.
 
diff --git a/Lib/dos-8x3/userdict.py b/Lib/dos-8x3/userdict.py
index 08f3161..50fee89 100755
--- a/Lib/dos-8x3/userdict.py
+++ b/Lib/dos-8x3/userdict.py
@@ -1,33 +1,36 @@
 # A more or less complete user-defined wrapper around dictionary objects
 
 class UserDict:
-    def __init__(self): self.data = {}
+    def __init__(self, dict=None):
+        self.data = {}
+        if dict is not None: self.update(dict)
     def __repr__(self): return repr(self.data)
     def __cmp__(self, dict):
-        if type(dict) == type(self.data):
-            return cmp(self.data, dict)
-        else:
+        if isinstance(dict, UserDict):
             return cmp(self.data, dict.data)
+        else:
+            return cmp(self.data, dict)
     def __len__(self): return len(self.data)
     def __getitem__(self, key): return self.data[key]
     def __setitem__(self, key, item): self.data[key] = item
     def __delitem__(self, key): del self.data[key]
-    def clear(self): return self.data.clear()
+    def clear(self): self.data.clear()
     def copy(self):
+        if self.__class__ is UserDict:
+            return UserDict(self.data)
         import copy
         return copy.copy(self)
     def keys(self): return self.data.keys()
     def items(self): return self.data.items()
     def values(self): return self.data.values()
     def has_key(self, key): return self.data.has_key(key)
-    def update(self, other):
-        if type(other) is type(self.data):
-            self.data.update(other)
+    def update(self, dict):
+        if isinstance(dict, UserDict):
+            self.data.update(dict.data)
+        elif isinstance(dict, type(self.data)):
+            self.data.update(dict)
         else:
-            for k, v in other.items():
+            for k, v in dict.items():
                 self.data[k] = v
     def get(self, key, failobj=None):
-        if self.data.has_key(key):
-            return self.data[key]
-        else:
-            return failobj
+        return self.data.get(key, failobj)
diff --git a/Lib/dos-8x3/userlist.py b/Lib/dos-8x3/userlist.py
index 93e4a7e..a60d8ce 100755
--- a/Lib/dos-8x3/userlist.py
+++ b/Lib/dos-8x3/userlist.py
@@ -1,52 +1,66 @@
 # A more or less complete user-defined wrapper around list objects
 
 class UserList:
-	def __init__(self, list = None):
-		self.data = []
-		if list is not None:
-			if type(list) == type(self.data):
-				self.data[:] = list
-			else:
-				self.data[:] = list.data[:]
-	def __repr__(self): return repr(self.data)
-	def __cmp__(self, list):
-		if type(list) == type(self.data):
-			return cmp(self.data, list)
-		else:
-			return cmp(self.data, list.data)
-	def __len__(self): return len(self.data)
-	def __getitem__(self, i): return self.data[i]
-	def __setitem__(self, i, item): self.data[i] = item
-	def __delitem__(self, i): del self.data[i]
-	def __getslice__(self, i, j):
-		userlist = self.__class__()
-		userlist.data[:] = self.data[i:j]
-		return userlist
-	def __setslice__(self, i, j, list):
-		if type(list) == type(self.data):
-			self.data[i:j] = list
-		else:
-			self.data[i:j] = list.data
-	def __delslice__(self, i, j): del self.data[i:j]
-	def __add__(self, list):
-		if type(list) == type(self.data):
-			return self.__class__(self.data + list)
-		else:
-			return self.__class__(self.data + list.data)
-	def __radd__(self, list):
-		if type(list) == type(self.data):
-			return self.__class__(list + self.data)
-		else:
-			return self.__class__(list.data + self.data)
-	def __mul__(self, n):
-		return self.__class__(self.data*n)
-	__rmul__ = __mul__
-	def append(self, item): self.data.append(item)
-	def insert(self, i, item): self.data.insert(i, item)
-	def pop(self, i=-1): return self.data.pop(i)
-	def remove(self, item): self.data.remove(item)
-	def count(self, item): return self.data.count(item)
-	def index(self, item): return self.data.index(item)
-	def reverse(self): self.data.reverse()
-	def sort(self, *args): apply(self.data.sort, args)
-	def extend(self, list): self.data.extend(list)
+    def __init__(self, list=None):
+        self.data = []
+        if list is not None:
+            if type(list) == type(self.data):
+                self.data[:] = list
+            else:
+                self.data[:] = list.data[:]
+    def __repr__(self): return repr(self.data)
+    def __cmp__(self, other):
+        if isinstance(other, UserList):
+            return cmp(self.data, other.data)
+        else:
+            return cmp(self.data, other)
+    def __len__(self): return len(self.data)
+    def __getitem__(self, i): return self.data[i]
+    def __setitem__(self, i, item): self.data[i] = item
+    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
+    def __setslice__(self, i, j, other):
+        i = max(i, 0); j = max(j, 0)
+        if isinstance(other, UserList):
+            self.data[i:j] = other.data
+        elif isinstance(other, type(self.data)):
+            self.data[i:j] = other
+        else:
+            self.data[i:j] = list(other)
+    def __delslice__(self, i, j):
+        i = max(i, 0); j = max(j, 0)
+        del self.data[i:j]
+    def __add__(self, other):
+        if isinstance(other, UserList):
+            return self.__class__(self.data + other.data)
+        elif isinstance(other, type(self.data)):
+            return self.__class__(self.data + other)
+        else:
+            return self.__class__(self.data + list(other))
+    def __radd__(self, other):
+        if isinstance(other, UserList):
+            return self.__class__(other.data + self.data)
+        elif isinstance(other, type(self.data)):
+            return self.__class__(other + self.data)
+        else:
+            return self.__class__(list(other) + self.data)
+    def __mul__(self, n):
+        return self.__class__(self.data*n)
+    __rmul__ = __mul__
+    def append(self, item): self.data.append(item)
+    def insert(self, i, item): self.data.insert(i, item)
+    def pop(self, i=-1): return self.data.pop(i)
+    def remove(self, item): self.data.remove(item)
+    def count(self, item): return self.data.count(item)
+    def index(self, item): return self.data.index(item)
+    def reverse(self): self.data.reverse()
+    def sort(self, *args): apply(self.data.sort, args)
+    def extend(self, other):
+        if isinstance(other, UserList):
+            self.data.extend(other.data)
+        else:
+            self.data.extend(other)