Adding new files, removing some.
diff --git a/Lib/dos-8x3/cookie.py b/Lib/dos-8x3/cookie.py
new file mode 100644
index 0000000..67259af
--- /dev/null
+++ b/Lib/dos-8x3/cookie.py
@@ -0,0 +1,726 @@
+#!/usr/bin/env python
+#
+
+####
+# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
+# 
+#                All Rights Reserved
+# 
+# Permission to use, copy, modify, and distribute this software
+# and its documentation for any purpose and without fee is hereby
+# granted, provided that the above copyright notice appear in all
+# copies and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Timothy O'Malley  not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission. 
+# 
+# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
+# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE. 
+#
+####
+# 
+# Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp 
+#   by Timothy O'Malley <timo@alum.mit.edu>
+#
+#  Cookie.py is a Python module for the handling of HTTP
+#  cookies as a Python dictionary.  See RFC 2109 for more
+#  information on cookies.
+#
+#  The original idea to treat Cookies as a dictionary came from
+#  Dave Mitchell (davem@magnet.com) in 1995, when he released the
+#  first version of nscookie.py.
+#
+####
+
+"""
+Here's a sample session to show how to use this module.
+At the moment, this is the only documentation.
+
+The Basics
+----------
+
+Importing is easy..
+
+   >>> import Cookie
+
+Most of the time you start by creating a cookie.  Cookies come in
+three flavors, each with slighly different encoding semanitcs, but
+more on that later.
+
+   >>> C = Cookie.SimpleCookie()
+   >>> C = Cookie.SerialCookie()
+   >>> C = Cookie.SmartCookie()
+
+[Note: Long-time users of Cookie.py will remember using
+Cookie.Cookie() to create an Cookie object.  Although deprecated, it
+is still supported by the code.  See the Backward Compatibility notes
+for more information.]
+
+Once you've created your Cookie, you can add values just as if it were
+a dictionary.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["fig"] = "newton"
+   >>> C["sugar"] = "wafer"
+   >>> print C
+   Set-Cookie: sugar=wafer;
+   Set-Cookie: fig=newton;
+
+Notice that the printable representation of a Cookie is the
+appropriate format for a Set-Cookie: header.  This is the
+default behavior.  You can change the header and printed
+attributes by using the the .output() function
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["rocky"] = "road"
+   >>> C["rocky"]["path"] = "/cookie"
+   >>> print C.output(header="Cookie:")
+   Cookie: rocky=road; Path=/cookie;
+   >>> print C.output(attrs=[], header="Cookie:")
+   Cookie: rocky=road;
+
+The load() method of a Cookie extracts cookies from a string.  In a
+CGI script, you would use this method to extract the cookies from the
+HTTP_COOKIE environment variable.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C.load("chips=ahoy; vienna=finger")
+   >>> print C
+   Set-Cookie: vienna=finger;
+   Set-Cookie: chips=ahoy;
+
+The load() method is darn-tootin smart about identifying cookies
+within a string.  Escaped quotation marks, nested semicolons, and other
+such trickeries do not confuse it.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
+   >>> print C
+   Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
+
+Each element of the Cookie also supports all of the RFC 2109
+Cookie attributes.  Here's an example which sets the Path
+attribute.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["oreo"] = "doublestuff"
+   >>> C["oreo"]["path"] = "/"
+   >>> print C
+   Set-Cookie: oreo="doublestuff"; Path=/;
+
+Each dictionary element has a 'value' attribute, which gives you
+back the value associated with the key. 
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["twix"] = "none for you"
+   >>> C["twix"].value
+   'none for you'
+
+
+A Bit More Advanced
+-------------------
+
+As mentioned before, there are three different flavors of Cookie
+objects, each with different encoding/decoding semantics.  This
+section briefly discusses the differences.
+
+SimpleCookie
+
+The SimpleCookie expects that all values should be standard strings.
+Just to be sure, SimpleCookie invokes the str() builtin to convert
+the value to a string, when the values are set dictionary-style.
+
+   >>> C = Cookie.SimpleCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   '7'
+   >>> C["string"].value
+   'seven'
+   >>> print C
+   Set-Cookie: number=7;
+   Set-Cookie: string=seven;
+
+ 
+SerialCookie
+
+The SerialCookie expects that all values should be serialized using
+cPickle (or pickle, if cPickle isn't available).  As a result of
+serializing, SerialCookie can save almost any Python object to a
+value, and recover the exact same object when the cookie has been
+returned.  (SerialCookie can yield some strange-looking cookie
+values, however.)
+
+   >>> C = Cookie.SerialCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   7
+   >>> C["string"].value
+   'seven'
+   >>> print C
+   Set-Cookie: number="I7\012.";
+   Set-Cookie: string="S'seven'\012p1\012.";
+
+Be warned, however, if SerialCookie cannot de-serialize a value (because
+it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
+
+
+SmartCookie
+
+The SmartCookie combines aspects of each of the other two flavors.
+When setting a value in a dictionary-fashion, the SmartCookie will
+serialize (ala cPickle) the value *if and only if* it isn't a
+Python string.  String objects are *not* serialized.  Similarly,
+when the load() method parses out values, it attempts to de-serialize
+the value.  If it fails, then it fallsback to treating the value
+as a string.
+
+   >>> C = Cookie.SmartCookie()
+   >>> C["number"] = 7
+   >>> C["string"] = "seven"
+   >>> C["number"].value
+   7
+   >>> C["string"].value
+   'seven'
+   >>> print C
+   Set-Cookie: number="I7\012.";
+   Set-Cookie: string=seven;
+
+
+Backwards Compatibility
+-----------------------
+
+In order to keep compatibilty with earlier versions of Cookie.py,
+it is still possible to use Cookie.Cookie() to create a Cookie.  In
+fact, this simply returns a SmartCookie.
+
+   >>> C = Cookie.Cookie()
+   >>> C.__class__
+   <class Cookie.SmartCookie at 99f88>
+
+
+Finis.
+"""  #"
+#     ^
+#     |----helps out font-lock
+
+#
+# Import our required modules
+# 
+import string, sys
+from UserDict import UserDict
+
+try:
+    from cPickle import dumps, loads
+except ImportError:
+    from pickle import dumps, loads
+
+try:
+    import re
+except ImportError:
+    raise ImportError, "Cookie.py requires 're' from Python 1.5 or later"
+
+
+#
+# Define an exception visible to External modules
+#
+class CookieError(Exception):
+    pass
+
+
+# These quoting routines conform to the RFC2109 specification, which in
+# turn references the character definitions from RFC2068.  They provide
+# a two-way quoting algorithm.  Any non-text character is translated
+# into a 4 character sequence: a forward-slash followed by the
+# three-digit octal equivalent of the character.  Any '\' or '"' is
+# quoted with a preceeding '\' slash.
+# 
+# These are taken from RFC2068 and RFC2109.
+#       _LegalChars       is the list of chars which don't require "'s
+#       _Translator       hash-table for fast quoting
+#
+_LegalChars       = string.letters + string.digits + "!#$%&'*+-.^_`|~"
+_Translator       = {
+    '\000' : '\\000',  '\001' : '\\001',  '\002' : '\\002',
+    '\003' : '\\003',  '\004' : '\\004',  '\005' : '\\005',
+    '\006' : '\\006',  '\007' : '\\007',  '\010' : '\\010',
+    '\011' : '\\011',  '\012' : '\\012',  '\013' : '\\013',
+    '\014' : '\\014',  '\015' : '\\015',  '\016' : '\\016',
+    '\017' : '\\017',  '\020' : '\\020',  '\021' : '\\021',
+    '\022' : '\\022',  '\023' : '\\023',  '\024' : '\\024',
+    '\025' : '\\025',  '\026' : '\\026',  '\027' : '\\027',
+    '\030' : '\\030',  '\031' : '\\031',  '\032' : '\\032',
+    '\033' : '\\033',  '\034' : '\\034',  '\035' : '\\035',
+    '\036' : '\\036',  '\037' : '\\037',
+
+    '"' : '\\"',       '\\' : '\\\\',
+
+    '\177' : '\\177',  '\200' : '\\200',  '\201' : '\\201',
+    '\202' : '\\202',  '\203' : '\\203',  '\204' : '\\204',
+    '\205' : '\\205',  '\206' : '\\206',  '\207' : '\\207',
+    '\210' : '\\210',  '\211' : '\\211',  '\212' : '\\212',
+    '\213' : '\\213',  '\214' : '\\214',  '\215' : '\\215',
+    '\216' : '\\216',  '\217' : '\\217',  '\220' : '\\220',
+    '\221' : '\\221',  '\222' : '\\222',  '\223' : '\\223',
+    '\224' : '\\224',  '\225' : '\\225',  '\226' : '\\226',
+    '\227' : '\\227',  '\230' : '\\230',  '\231' : '\\231',
+    '\232' : '\\232',  '\233' : '\\233',  '\234' : '\\234',
+    '\235' : '\\235',  '\236' : '\\236',  '\237' : '\\237',
+    '\240' : '\\240',  '\241' : '\\241',  '\242' : '\\242',
+    '\243' : '\\243',  '\244' : '\\244',  '\245' : '\\245',
+    '\246' : '\\246',  '\247' : '\\247',  '\250' : '\\250',
+    '\251' : '\\251',  '\252' : '\\252',  '\253' : '\\253',
+    '\254' : '\\254',  '\255' : '\\255',  '\256' : '\\256',
+    '\257' : '\\257',  '\260' : '\\260',  '\261' : '\\261',
+    '\262' : '\\262',  '\263' : '\\263',  '\264' : '\\264',
+    '\265' : '\\265',  '\266' : '\\266',  '\267' : '\\267',
+    '\270' : '\\270',  '\271' : '\\271',  '\272' : '\\272',
+    '\273' : '\\273',  '\274' : '\\274',  '\275' : '\\275',
+    '\276' : '\\276',  '\277' : '\\277',  '\300' : '\\300',
+    '\301' : '\\301',  '\302' : '\\302',  '\303' : '\\303',
+    '\304' : '\\304',  '\305' : '\\305',  '\306' : '\\306',
+    '\307' : '\\307',  '\310' : '\\310',  '\311' : '\\311',
+    '\312' : '\\312',  '\313' : '\\313',  '\314' : '\\314',
+    '\315' : '\\315',  '\316' : '\\316',  '\317' : '\\317',
+    '\320' : '\\320',  '\321' : '\\321',  '\322' : '\\322',
+    '\323' : '\\323',  '\324' : '\\324',  '\325' : '\\325',
+    '\326' : '\\326',  '\327' : '\\327',  '\330' : '\\330',
+    '\331' : '\\331',  '\332' : '\\332',  '\333' : '\\333',
+    '\334' : '\\334',  '\335' : '\\335',  '\336' : '\\336',
+    '\337' : '\\337',  '\340' : '\\340',  '\341' : '\\341',
+    '\342' : '\\342',  '\343' : '\\343',  '\344' : '\\344',
+    '\345' : '\\345',  '\346' : '\\346',  '\347' : '\\347',
+    '\350' : '\\350',  '\351' : '\\351',  '\352' : '\\352',
+    '\353' : '\\353',  '\354' : '\\354',  '\355' : '\\355',
+    '\356' : '\\356',  '\357' : '\\357',  '\360' : '\\360',
+    '\361' : '\\361',  '\362' : '\\362',  '\363' : '\\363',
+    '\364' : '\\364',  '\365' : '\\365',  '\366' : '\\366',
+    '\367' : '\\367',  '\370' : '\\370',  '\371' : '\\371',
+    '\372' : '\\372',  '\373' : '\\373',  '\374' : '\\374',
+    '\375' : '\\375',  '\376' : '\\376',  '\377' : '\\377'
+    }
+
+def _quote(str, LegalChars=_LegalChars,
+    join=string.join, idmap=string._idmap, translate=string.translate):
+    #
+    # If the string does not need to be double-quoted,
+    # then just return the string.  Otherwise, surround
+    # the string in doublequotes and precede quote (with a \)
+    # special characters.
+    #
+    if "" == translate(str, idmap, LegalChars):
+        return str
+    else:
+        return '"' + join( map(_Translator.get, str, str), "" ) + '"'    
+# end _quote
+
+
+_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
+_QuotePatt = re.compile(r"[\\].")
+
+def _unquote(str, join=string.join, atoi=string.atoi):
+    # If there aren't any doublequotes,
+    # then there can't be any special characters.  See RFC 2109.
+    if  len(str) < 2:
+        return str
+    if str[0] != '"' or str[-1] != '"':
+        return str
+
+    # We have to assume that we must decode this string.
+    # Down to work.
+
+    # Remove the "s
+    str = str[1:-1]
+
+    # Check for special sequences.  Examples:
+    #    \012 --> \n
+    #    \"   --> "
+    #
+    i = 0
+    n = len(str)
+    res = []
+    while 0 <= i < n:
+        Omatch = _OctalPatt.search(str, i)
+        Qmatch = _QuotePatt.search(str, i)
+        if not Omatch and not Qmatch:              # Neither matched
+            res.append(str[i:])
+            break
+        # else:
+        j = k = -1
+        if Omatch: j = Omatch.start(0)
+        if Qmatch: k = Qmatch.start(0)
+        if Qmatch and ( not Omatch or k < j ):     # QuotePatt matched
+            res.append(str[i:k])
+            res.append(str[k+1])
+            i = k+2
+        else:                                      # OctalPatt matched
+            res.append(str[i:j])
+            res.append( chr( atoi(str[j+1:j+4], 8) ) )
+            i = j+4
+    return join(res, "")
+# end _unquote
+
+# The _getdate() routine is used to set the expiration time in
+# the cookie's HTTP header.      By default, _getdate() returns the
+# current time in the appropriate "expires" format for a 
+# Set-Cookie header.     The one optional argument is an offset from
+# now, in seconds.      For example, an offset of -3600 means "one hour ago".
+# The offset may be a floating point number.
+#
+
+_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+_monthname = [None,
+              'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
+def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
+    from time import gmtime, time
+    now = time()
+    year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
+    return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \
+           (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
+
+
+#
+# A class to hold ONE key,value pair.
+# In a cookie, each such pair may have several attributes.
+#       so this class is used to keep the attributes associated
+#       with the appropriate key,value pair.
+# This class also includes a coded_value attribute, which
+#       is used to hold the network representation of the
+#       value.  This is most useful when Python objects are
+#       pickled for network transit.
+#
+
+class Morsel(UserDict):
+    # RFC 2109 lists these attributes as reserved:
+    #   path       comment         domain
+    #   max-age    secure      version
+    # 
+    # For historical reasons, these attributes are also reserved:
+    #   expires
+    #
+    # This dictionary provides a mapping from the lowercase
+    # variant on the left to the appropriate traditional
+    # formatting on the right.
+    _reserved = { "expires" : "expires",
+                   "path"        : "Path",
+                   "comment" : "Comment",
+                   "domain"      : "Domain",
+                   "max-age" : "Max-Age",
+                   "secure"      : "secure",
+                   "version" : "Version",
+                   }
+    _reserved_keys = _reserved.keys()
+
+    def __init__(self):
+        # Set defaults
+        self.key = self.value = self.coded_value = None
+        UserDict.__init__(self)
+
+        # Set default attributes
+        for K in self._reserved_keys:
+            UserDict.__setitem__(self, K, "")
+    # end __init__
+
+    def __setitem__(self, K, V):
+        K = string.lower(K)
+        if not K in self._reserved_keys:
+            raise CookieError("Invalid Attribute %s" % K)
+        UserDict.__setitem__(self, K, V)
+    # end __setitem__
+
+    def isReservedKey(self, K):
+        return string.lower(K) in self._reserved_keys
+    # end isReservedKey
+
+    def set(self, key, val, coded_val,
+            LegalChars=_LegalChars,
+            idmap=string._idmap, translate=string.translate ):
+        # First we verify that the key isn't a reserved word
+        # Second we make sure it only contains legal characters
+        if string.lower(key) in self._reserved_keys:
+            raise CookieError("Attempt to set a reserved key: %s" % key)
+        if "" != translate(key, idmap, LegalChars):
+            raise CookieError("Illegal key value: %s" % key)
+
+        # It's a good key, so save it.
+        self.key                 = key
+        self.value               = val
+        self.coded_value         = coded_val
+    # end set
+
+    def output(self, attrs=None, header = "Set-Cookie:"):
+        return "%s %s" % ( header, self.OutputString(attrs) )
+
+    __str__ = output
+
+    def __repr__(self):
+        return '<%s: %s=%s>' % (self.__class__.__name__,
+                                self.key, repr(self.value) )
+
+    def js_output(self, attrs=None):
+        # Print javascript
+        return """
+        <SCRIPT LANGUAGE="JavaScript">
+        <!-- begin hiding
+        document.cookie = \"%s\"
+        // end hiding -->
+        </script>
+        """ % ( self.OutputString(attrs), )
+    # end js_output()
+
+    def OutputString(self, attrs=None):
+        # Build up our result
+        #
+        result = []
+        RA = result.append
+
+        # First, the key=value pair
+        RA("%s=%s;" % (self.key, self.coded_value))
+
+        # Now add any defined attributes
+        if attrs == None:
+            attrs = self._reserved_keys
+        for K,V in self.items():
+            if V == "": continue
+            if K not in attrs: continue
+            if K == "expires" and type(V) == type(1):
+                RA("%s=%s;" % (self._reserved[K], _getdate(V)))
+            elif K == "max-age" and type(V) == type(1):
+                RA("%s=%d;" % (self._reserved[K], V))
+            elif K == "secure":
+                RA("%s;" % self._reserved[K])
+            else:
+                RA("%s=%s;" % (self._reserved[K], V))
+
+        # Return the result
+        return string.join(result, " ")
+    # end OutputString
+# end Morsel class
+
+
+
+#
+# Pattern for finding cookie
+#
+# This used to be strict parsing based on the RFC2109 and RFC2068
+# specifications.  I have since discovered that MSIE 3.0x doesn't
+# follow the character rules outlined in those specs.  As a
+# result, the parsing rules here are less strict.
+#
+
+_LegalCharsPatt  = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{]"
+_CookiePattern = re.compile(
+    r"(?x)"                       # This is a Verbose pattern
+    r"(?P<key>"                   # Start of group 'key'
+    ""+ _LegalCharsPatt +"+"        # Any word of at least one letter
+    r")"                          # End of group 'key'
+    r"\s*=\s*"                    # Equal Sign
+    r"(?P<val>"                   # Start of group 'val'
+    r'"(?:[^\\"]|\\.)*"'            # Any doublequoted string
+    r"|"                            # or
+    ""+ _LegalCharsPatt +"*"        # Any word or empty string
+    r")"                          # End of group 'val'
+    r"\s*;?"                      # Probably ending in a semi-colon
+    )
+
+
+# At long last, here is the cookie class.
+#   Using this class is almost just like using a dictionary.
+# See this module's docstring for example usage.
+#
+class BaseCookie(UserDict):
+    # A container class for a set of Morsels
+    #
+
+    def value_decode(self, val):
+        """real_value, coded_value = value_decode(STRING)
+        Called prior to setting a cookie's value from the network
+        representation.  The VALUE is the value read from HTTP
+        header.
+        Override this function to modify the behavior of cookies.
+        """
+        return val, val
+    # end value_encode
+
+    def value_encode(self, val):
+        """real_value, coded_value = value_encode(VALUE)
+        Called prior to setting a cookie's value from the dictionary
+        representation.  The VALUE is the value being assigned.
+        Override this function to modify the behavior of cookies.
+        """
+        strval = str(val)
+        return strval, strval
+    # end value_encode
+
+    def __init__(self, input=None):
+        UserDict.__init__(self)
+        if input: self.load(input)
+    # end __init__
+
+    def __set(self, key, real_value, coded_value):
+        """Private method for setting a cookie's value"""
+        M = self.get(key, Morsel())
+        M.set(key, real_value, coded_value)
+        UserDict.__setitem__(self, key, M)
+    # end __set
+
+    def __setitem__(self, key, value):
+        """Dictionary style assignment."""
+        rval, cval = self.value_encode(value)
+        self.__set(key, rval, cval)
+    # end __setitem__
+
+    def output(self, attrs=None, header="Set-Cookie:", sep="\n"):
+        """Return a string suitable for HTTP."""
+        result = []
+        for K,V in self.items():
+            result.append( V.output(attrs, header) )
+        return string.join(result, sep)
+    # end output
+
+    __str__ = output
+
+    def __repr__(self):
+        L = []
+        for K,V in self.items():
+            L.append( '%s=%s' % (K,repr(V.value) ) )
+        return '<%s: %s>' % (self.__class__.__name__, string.join(L))
+
+    def js_output(self, attrs=None):
+        """Return a string suitable for JavaScript."""
+        result = []
+        for K,V in self.items():
+            result.append( V.js_output(attrs) )
+        return string.join(result, "")
+    # end js_output
+
+    def load(self, rawdata):
+        """Load cookies from a string (presumably HTTP_COOKIE) or
+        from a dictionary.  Loading cookies from a dictionary 'd'
+        is equivalent to calling:
+            map(Cookie.__setitem__, d.keys(), d.values())
+        """
+        if type(rawdata) == type(""):
+            self.__ParseString(rawdata)
+        else:
+            self.update(rawdata)
+        return
+    # end load()
+
+    def __ParseString(self, str, patt=_CookiePattern):
+        i = 0            # Our starting point
+        n = len(str)     # Length of string
+        M = None         # current morsel
+
+        while 0 <= i < n:
+            # Start looking for a cookie
+            match = patt.search(str, i)
+            if not match: break          # No more cookies
+
+            K,V = match.group("key"), match.group("val")
+            i = match.end(0)
+
+            # Parse the key, value in case it's metainfo
+            if K[0] == "$":
+                # We ignore attributes which pertain to the cookie
+                # mechanism as a whole.  See RFC 2109.
+                # (Does anyone care?)
+                if M:
+                    M[ K[1:] ] = V
+            elif string.lower(K) in Morsel._reserved_keys:
+                if M:
+                    M[ K ] = _unquote(V)
+            else:
+                rval, cval = self.value_decode(V)
+                self.__set(K, rval, cval)
+                M = self[K]
+    # end __ParseString
+# end BaseCookie class
+
+class SimpleCookie(BaseCookie):
+    """SimpleCookie
+    SimpleCookie supports strings as cookie values.  When setting
+    the value using the dictionary assignment notation, SimpleCookie
+    calls the builtin str() to convert the value to a string.  Values
+    received from HTTP are kept as strings.
+    """
+    def value_decode(self, val):
+        return _unquote( val ), val
+    def value_encode(self, val):
+        strval = str(val)
+        return strval, _quote( strval )
+# end SimpleCookie
+
+class SerialCookie(BaseCookie):
+    """SerialCookie
+    SerialCookie supports arbitrary objects as cookie values. All
+    values are serialized (using cPickle) before being sent to the
+    client.  All incoming values are assumed to be valid Pickle
+    representations.  IF AN INCOMING VALUE IS NOT IN A VALID PICKLE
+    FORMAT, THEN AN EXCEPTION WILL BE RAISED.
+
+    Note: Large cookie values add overhead because they must be
+    retransmitted on every HTTP transaction.
+
+    Note: HTTP has a 2k limit on the size of a cookie.  This class
+    does not check for this limit, so be careful!!!
+    """
+    def value_decode(self, val):
+        # This could raise an exception!
+        return loads( _unquote(val) ), val
+    def value_encode(self, val):
+        return val, _quote( dumps(val) )
+# end SerialCookie
+
+class SmartCookie(BaseCookie):
+    """SmartCookie
+    SmartCookie supports arbitrary objects as cookie values.  If the
+    object is a string, then it is quoted.  If the object is not a
+    string, however, then SmartCookie will use cPickle to serialize
+    the object into a string representation.
+
+    Note: Large cookie values add overhead because they must be
+    retransmitted on every HTTP transaction.
+
+    Note: HTTP has a 2k limit on the size of a cookie.  This class
+    does not check for this limit, so be careful!!!
+    """
+    def value_decode(self, val):
+        strval = _unquote(val)
+        try:
+            return loads(strval), val
+        except:
+            return strval, val
+    def value_encode(self, val):
+        if type(val) == type(""):
+            return val, _quote(val)
+        else:
+            return val, _quote( dumps(val) )
+# end SmartCookie
+
+
+###########################################################
+# Backwards Compatibility:  Don't break any existing code!
+
+# We provide Cookie() as an alias for SmartCookie()
+Cookie = SmartCookie
+
+#
+###########################################################
+
+
+
+#Local Variables:
+#tab-width: 4
+#end:
diff --git a/Lib/dos-8x3/exceptio.py b/Lib/dos-8x3/exceptio.py
deleted file mode 100644
index 43d1c2d..0000000
--- a/Lib/dos-8x3/exceptio.py
+++ /dev/null
@@ -1,247 +0,0 @@
-"""Class based built-in exception hierarchy.
-
-New with Python 1.5, all standard built-in exceptions are now class objects by
-default.  This gives Python's exception handling mechanism a more
-object-oriented feel.  Traditionally they were string objects.  Python will
-fallback to string based exceptions if the interpreter is invoked with the -X
-option, or if some failure occurs during class exception initialization (in
-this case a warning will be printed).
-
-Most existing code should continue to work with class based exceptions.  Some
-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 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
-you define your own class based exceptions, they should be derived from
-Exception.
-
-Exception(*)
- |
- +-- SystemExit
- +-- StandardError(*)
-      |
-      +-- KeyboardInterrupt
-      +-- ImportError
-      +-- EnvironmentError(*)
-      |    |
-      |    +-- IOError
-      |    +-- OSError(*)
-      |         |
-      |         +-- WindowsError(*)
-      |
-      +-- EOFError
-      +-- RuntimeError
-      |    |
-      |    +-- NotImplementedError(*)
-      |
-      +-- NameError
-      |    |
-      |    +-- UnboundLocalError(*)
-      |
-      +-- AttributeError
-      +-- SyntaxError
-      +-- TypeError
-      +-- AssertionError
-      +-- LookupError(*)
-      |    |
-      |    +-- IndexError
-      |    +-- KeyError
-      |
-      +-- ArithmeticError(*)
-      |    |
-      |    +-- OverflowError
-      |    +-- ZeroDivisionError
-      |    +-- FloatingPointError
-      |
-      +-- ValueError
-      |    |
-      |    +-- UnicodeError(*)
-      |
-      +-- SystemError
-      +-- MemoryError
-"""
-
-class Exception:
-    """Proposed base class for all exceptions."""
-    def __init__(self, *args):
-        self.args = args
-
-    def __str__(self):
-        if not self.args:
-            return ''
-        elif len(self.args) == 1:
-            return str(self.args[0])
-        else:
-            return str(self.args)
-
-    def __getitem__(self, i):
-        return self.args[i]
-
-class StandardError(Exception):
-    """Base class for all standard Python exceptions."""
-    pass
-
-class SyntaxError(StandardError):
-    """Invalid syntax."""
-    filename = lineno = offset = text = None
-    msg = ""
-    def __init__(self, *args):
-        self.args = args
-        if len(self.args) >= 1:
-            self.msg = self.args[0]
-        if len(self.args) == 2:
-            info = self.args[1]
-            try:
-                self.filename, self.lineno, self.offset, self.text = info
-            except:
-                pass
-    def __str__(self):
-        return str(self.msg)
-
-class EnvironmentError(StandardError):
-    """Base class for I/O related errors."""
-    def __init__(self, *args):
-        self.args = args
-        self.errno = None
-        self.strerror = None
-        self.filename = None
-        if len(args) == 3:
-            # open() errors give third argument which is the filename.  BUT,
-            # so common in-place unpacking doesn't break, e.g.:
-            #
-            # except IOError, (errno, strerror):
-            #
-            # we hack args so that it only contains two items.  This also
-            # means we need our own __str__() which prints out the filename
-            # when it was supplied.
-            self.errno, self.strerror, self.filename = args
-            self.args = args[0:2]
-        if len(args) == 2:
-            # common case: PyErr_SetFromErrno()
-            self.errno, self.strerror = args
-
-    def __str__(self):
-        if self.filename is not None:
-            return '[Errno %s] %s: %s' % (self.errno, self.strerror,
-                                          repr(self.filename))
-        elif self.errno and self.strerror:
-            return '[Errno %s] %s' % (self.errno, self.strerror)
-        else:
-            return StandardError.__str__(self)
-
-class IOError(EnvironmentError):
-    """I/O operation failed."""
-    pass
-
-class OSError(EnvironmentError):
-    """OS system call failed."""
-    pass
-
-class WindowsError(OSError):
-    """MS-Windows OS system call failed."""
-    pass
-
-class RuntimeError(StandardError):
-    """Unspecified run-time error."""
-    pass
-
-class NotImplementedError(RuntimeError):
-    """Method or function hasn't been implemented yet."""
-    pass
-
-class SystemError(StandardError):
-    """Internal error in the Python interpreter.
-
-    Please report this to the Python maintainer, along with the traceback,
-    the Python version, and the hardware/OS platform and version."""
-    pass
-
-class EOFError(StandardError):
-    """Read beyond end of file."""
-    pass
-
-class ImportError(StandardError):
-    """Import can't find module, or can't find name in module."""
-    pass
-
-class TypeError(StandardError):
-    """Inappropriate argument type."""
-    pass
-
-class ValueError(StandardError):
-    """Inappropriate argument value (of correct type)."""
-    pass
-
-class KeyboardInterrupt(StandardError):
-    """Program interrupted by user."""
-    pass
-
-class AssertionError(StandardError):
-    """Assertion failed."""
-    pass
-
-class ArithmeticError(StandardError):
-    """Base class for arithmetic errors."""
-    pass
-
-class OverflowError(ArithmeticError):
-    """Result too large to be represented."""
-    pass
-
-class FloatingPointError(ArithmeticError):
-    """Floating point operation failed."""
-    pass
-
-class ZeroDivisionError(ArithmeticError):
-    """Second argument to a division or modulo operation was zero."""
-    pass
-
-class LookupError(StandardError):
-    """Base class for lookup errors."""
-    pass
-
-class IndexError(LookupError):
-    """Sequence index out of range."""
-    pass
-
-class KeyError(LookupError):
-    """Mapping key not found."""
-    pass
-
-class AttributeError(StandardError):
-    """Attribute not found."""
-    pass
-
-class NameError(StandardError):
-    """Name not found globally."""
-    pass
-
-class UnboundLocalError(NameError):
-    """Local name referenced but not bound to a value."""
-    pass
-
-class UnicodeError(ValueError):
-    """Unicode related error."""
-    pass
-
-class MemoryError(StandardError):
-    """Out of memory."""
-    pass
-
-class SystemExit(Exception):
-    """Request to exit from the interpreter."""
-    def __init__(self, *args):
-        self.args = args
-        if len(args) == 0:
-            self.code = None
-        elif len(args) == 1:
-            self.code = args[0]
-        else:
-            self.code = args
diff --git a/Lib/dos-8x3/string_t.py b/Lib/dos-8x3/string_t.py
new file mode 100644
index 0000000..d4041be
--- /dev/null
+++ b/Lib/dos-8x3/string_t.py
@@ -0,0 +1,202 @@
+"""Common tests shared by test_string and test_userstring"""
+
+import string
+
+transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377'
+
+from UserList import UserList
+
+class Sequence:
+    def __init__(self): self.seq = 'wxyz'
+    def __len__(self): return len(self.seq)
+    def __getitem__(self, i): return self.seq[i]
+
+class BadSeq1(Sequence):
+    def __init__(self): self.seq = [7, 'hello', 123L]
+
+class BadSeq2(Sequence):
+    def __init__(self): self.seq = ['a', 'b', 'c']
+    def __len__(self): return 8
+
+def run_module_tests(test):
+    """Run all tests that exercise a function in the string module"""
+
+    test('atoi', " 1 ", 1)
+    test('atoi', " 1x", ValueError)
+    test('atoi', " x1 ", ValueError)
+    test('atol', "  1  ", 1L)
+    test('atol', "  1x ", ValueError)
+    test('atol', "  x1 ", ValueError)
+    test('atof', "  1  ", 1.0)
+    test('atof', "  1x ", ValueError)
+    test('atof', "  x1 ", ValueError)
+
+    test('maketrans', 'abc', transtable, 'xyz')
+    test('maketrans', 'abc', ValueError, 'xyzq')
+
+    # join now works with any sequence type
+    test('join', ['a', 'b', 'c', 'd'], 'a b c d')
+    test('join', ('a', 'b', 'c', 'd'), 'abcd', '')
+    test('join', Sequence(), 'w x y z')
+    test('join', 7, TypeError)
+
+    test('join', BadSeq1(), TypeError)
+    test('join', BadSeq2(), 'a b c')
+
+    # try a few long ones
+    print string.join(['x' * 100] * 100, ':')
+    print string.join(('x' * 100,) * 100, ':')
+
+
+def run_method_tests(test):
+    """Run all tests that exercise a method of a string object"""
+
+    test('capitalize', ' hello ', ' hello ')
+    test('capitalize', 'hello ', 'Hello ')
+    test('find', 'abcdefghiabc', 0, 'abc')
+    test('find', 'abcdefghiabc', 9, 'abc', 1)
+    test('find', 'abcdefghiabc', -1, 'def', 4)
+    test('rfind', 'abcdefghiabc', 9, 'abc')
+    test('lower', 'HeLLo', 'hello')
+    test('lower', 'hello', 'hello')
+    test('upper', 'HeLLo', 'HELLO')
+    test('upper', 'HELLO', 'HELLO')
+
+    test('title', ' hello ', ' Hello ')
+    test('title', 'hello ', 'Hello ')
+    test('title', "fOrMaT thIs aS titLe String", 'Format This As Title String')
+    test('title', "fOrMaT,thIs-aS*titLe;String", 'Format,This-As*Title;String')
+    test('title', "getInt", 'Getint')
+
+    test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab      def\ng       hi')
+    test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab      def\ng       hi', 8)
+    test('expandtabs', 'abc\rab\tdef\ng\thi', 'abc\rab  def\ng   hi', 4)
+    test('expandtabs', 'abc\r\nab\tdef\ng\thi', 'abc\r\nab  def\ng   hi', 4)
+
+    test('islower', 'a', 1)
+    test('islower', 'A', 0)
+    test('islower', '\n', 0)
+    test('islower', 'abc', 1)
+    test('islower', 'aBc', 0)
+    test('islower', 'abc\n', 1)
+
+    test('isupper', 'a', 0)
+    test('isupper', 'A', 1)
+    test('isupper', '\n', 0)
+    test('isupper', 'ABC', 1)
+    test('isupper', 'AbC', 0)
+    test('isupper', 'ABC\n', 1)
+
+    test('istitle', 'a', 0)
+    test('istitle', 'A', 1)
+    test('istitle', '\n', 0)
+    test('istitle', 'A Titlecased Line', 1)
+    test('istitle', 'A\nTitlecased Line', 1)
+    test('istitle', 'A Titlecased, Line', 1)
+    test('istitle', 'Not a capitalized String', 0)
+    test('istitle', 'Not\ta Titlecase String', 0)
+    test('istitle', 'Not--a Titlecase String', 0)
+
+    test('isalpha', 'a', 1)
+    test('isalpha', 'A', 1)
+    test('isalpha', '\n', 0)
+    test('isalpha', 'abc', 1)
+    test('isalpha', 'aBc123', 0)
+    test('isalpha', 'abc\n', 0)
+
+    test('isalnum', 'a', 1)
+    test('isalnum', 'A', 1)
+    test('isalnum', '\n', 0)
+    test('isalnum', '123abc456', 1)
+    test('isalnum', 'a1b3c', 1)
+    test('isalnum', 'aBc000 ', 0)
+    test('isalnum', 'abc\n', 0)
+
+    # join now works with any sequence type
+    test('join', ' ', 'a b c d', ['a', 'b', 'c', 'd'])
+    test('join', '', 'abcd', ('a', 'b', 'c', 'd'))
+    test('join', ' ', 'w x y z', Sequence())
+    test('join', 'a', 'abc', ('abc',))
+    test('join', 'a', 'z', UserList(['z']))
+    test('join', u'.', u'a.b.c', ['a', 'b', 'c'])
+    test('join', '.', u'a.b.c', [u'a', 'b', 'c'])
+    test('join', '.', u'a.b.c', ['a', u'b', 'c'])
+    test('join', '.', u'a.b.c', ['a', 'b', u'c'])
+    test('join', '.', TypeError, ['a', u'b', 3])
+    for i in [5, 25, 125]:
+        test('join', '-', ((('a' * i) + '-') * i)[:-1],
+             ['a' * i] * i)
+
+    test('join', ' ', TypeError, BadSeq1())
+    test('join', ' ', 'a b c', BadSeq2())
+
+    test('splitlines', "abc\ndef\n\rghi", ['abc', 'def', '', 'ghi'])
+    test('splitlines', "abc\ndef\n\r\nghi", ['abc', 'def', '', 'ghi'])
+    test('splitlines', "abc\ndef\r\nghi", ['abc', 'def', 'ghi'])
+    test('splitlines', "abc\ndef\r\nghi\n", ['abc', 'def', 'ghi'])
+    test('splitlines', "abc\ndef\r\nghi\n\r", ['abc', 'def', 'ghi', ''])
+    test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc', 'def', 'ghi', ''])
+    test('splitlines', "\nabc\ndef\r\nghi\n\r", ['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], 1)
+
+    test('split', 'this is the split function',
+         ['this', 'is', 'the', 'split', 'function'])
+    test('split', 'a|b|c|d', ['a', 'b', 'c', 'd'], '|')
+    test('split', 'a|b|c|d', ['a', 'b', 'c|d'], '|', 2)
+    test('split', 'a b c d', ['a', 'b c d'], None, 1)
+    test('split', 'a b c d', ['a', 'b', 'c d'], None, 2)
+    test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 3)
+    test('split', 'a b c d', ['a', 'b', 'c', 'd'], None, 4)
+    test('split', 'a b c d', ['a b c d'], None, 0)
+    test('split', 'a  b  c  d', ['a', 'b', 'c  d'], None, 2)
+    test('split', 'a b c d ', ['a', 'b', 'c', 'd'])
+
+    test('strip', '   hello   ', 'hello')
+    test('lstrip', '   hello   ', 'hello   ')
+    test('rstrip', '   hello   ', '   hello')
+    test('strip', 'hello', 'hello')
+
+    test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS')
+    test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def')
+
+    table = string.maketrans('a', 'A')
+    test('translate', 'abc', 'Abc', table)
+    test('translate', 'xyz', 'xyz', table)
+
+    test('replace', 'one!two!three!', 'one@two!three!', '!', '@', 1)
+    test('replace', 'one!two!three!', 'onetwothree', '!', '')
+    test('replace', 'one!two!three!', 'one@two@three!', '!', '@', 2)
+    test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 3)
+    test('replace', 'one!two!three!', 'one@two@three@', '!', '@', 4)
+    test('replace', 'one!two!three!', 'one!two!three!', '!', '@', 0)
+    test('replace', 'one!two!three!', 'one@two@three@', '!', '@')
+    test('replace', 'one!two!three!', 'one!two!three!', 'x', '@')
+    test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2)
+
+    test('startswith', 'hello', 1, 'he')
+    test('startswith', 'hello', 1, 'hello')
+    test('startswith', 'hello', 0, 'hello world')
+    test('startswith', 'hello', 1, '')
+    test('startswith', 'hello', 0, 'ello')
+    test('startswith', 'hello', 1, 'ello', 1)
+    test('startswith', 'hello', 1, 'o', 4)
+    test('startswith', 'hello', 0, 'o', 5)
+    test('startswith', 'hello', 1, '', 5)
+    test('startswith', 'hello', 0, 'lo', 6)
+    test('startswith', 'helloworld', 1, 'lowo', 3)
+    test('startswith', 'helloworld', 1, 'lowo', 3, 7)
+    test('startswith', 'helloworld', 0, 'lowo', 3, 6)
+
+    test('endswith', 'hello', 1, 'lo')
+    test('endswith', 'hello', 0, 'he')
+    test('endswith', 'hello', 1, '')
+    test('endswith', 'hello', 0, 'hello world')
+    test('endswith', 'helloworld', 0, 'worl')
+    test('endswith', 'helloworld', 1, 'worl', 3, 9)
+    test('endswith', 'helloworld', 1, 'world', 3, 12)
+    test('endswith', 'helloworld', 1, 'lowo', 1, 7)
+    test('endswith', 'helloworld', 1, 'lowo', 2, 7)
+    test('endswith', 'helloworld', 1, 'lowo', 3, 7)
+    test('endswith', 'helloworld', 0, 'lowo', 4, 7)
+    test('endswith', 'helloworld', 0, 'lowo', 3, 8)
+    test('endswith', 'ab', 0, 'ab', 0, 1)
+    test('endswith', 'ab', 0, 'ab', 0, 0)
diff --git a/Lib/dos-8x3/test_aug.py b/Lib/dos-8x3/test_aug.py
new file mode 100644
index 0000000..a01195e
--- /dev/null
+++ b/Lib/dos-8x3/test_aug.py
@@ -0,0 +1,232 @@
+
+# Augmented assignment test.
+
+x = 2
+x += 1
+x *= 2
+x **= 2
+x -= 8
+x /= 2
+x %= 12
+x &= 2
+x |= 5
+x ^= 1
+
+print x
+
+x = [2]
+x[0] += 1
+x[0] *= 2
+x[0] **= 2
+x[0] -= 8
+x[0] /= 2
+x[0] %= 12
+x[0] &= 2
+x[0] |= 5
+x[0] ^= 1
+
+print x
+
+x = {0: 2}
+x[0] += 1
+x[0] *= 2
+x[0] **= 2
+x[0] -= 8
+x[0] /= 2
+x[0] %= 12
+x[0] &= 2
+x[0] |= 5
+x[0] ^= 1
+
+print x[0]
+
+x = [1,2]
+x += [3,4]
+x *= 2
+
+print x
+
+x = [1, 2, 3]
+y = x
+x[1:2] *= 2
+y[1:2] += [1]
+
+print x
+print x is y
+
+class aug_test:
+	def __init__(self, value):
+		self.val = value
+	def __radd__(self, val):
+		return self.val + val
+	def __add__(self, val):
+		return aug_test(self.val + val)
+
+
+class aug_test2(aug_test):
+	def __iadd__(self, val):
+		self.val = self.val + val
+		return self
+
+class aug_test3(aug_test):
+	def __iadd__(self, val):
+		return aug_test3(self.val + val)
+
+x = aug_test(1)
+y = x
+x += 10
+
+print isinstance(x, aug_test)
+print y is not x 
+print x.val
+
+x = aug_test2(2)
+y = x
+x += 10
+
+print y is x
+print x.val
+
+x = aug_test3(3)
+y = x
+x += 10
+
+print isinstance(x, aug_test3)
+print y is not x
+print x.val
+
+class testall:
+
+	def __add__(self, val):
+		print "__add__ called"
+	def __radd__(self, val):
+		print "__radd__ called"
+	def __iadd__(self, val):
+		print "__iadd__ called"
+		return self
+
+	def __sub__(self, val):
+		print "__sub__ called"
+	def __rsub__(self, val):
+		print "__rsub__ called"
+	def __isub__(self, val):
+		print "__isub__ called"
+		return self
+
+	def __mul__(self, val):
+		print "__mul__ called"
+	def __rmul__(self, val):
+		print "__rmul__ called"
+	def __imul__(self, val):
+		print "__imul__ called"
+		return self
+
+	def __div__(self, val):
+		print "__div__ called"
+	def __rdiv__(self, val):
+		print "__rdiv__ called"
+	def __idiv__(self, val):
+		print "__idiv__ called"
+		return self
+
+	def __mod__(self, val):
+		print "__mod__ called"
+	def __rmod__(self, val):
+		print "__rmod__ called"
+	def __imod__(self, val):
+		print "__imod__ called"
+		return self
+
+	def __pow__(self, val):
+		print "__pow__ called"
+	def __rpow__(self, val):
+		print "__rpow__ called"
+	def __ipow__(self, val):
+		print "__ipow__ called"
+		return self
+
+	def __or__(self, val):
+		print "__or__ called"
+	def __ror__(self, val):
+		print "__ror__ called"
+	def __ior__(self, val):
+		print "__ior__ called"
+		return self
+
+	def __and__(self, val):
+		print "__and__ called"
+	def __rand__(self, val):
+		print "__rand__ called"
+	def __iand__(self, val):
+		print "__iand__ called"
+		return self
+
+	def __xor__(self, val):
+		print "__xor__ called"
+	def __rxor__(self, val):
+		print "__rxor__ called"
+	def __ixor__(self, val):
+		print "__ixor__ called"
+		return self
+
+	def __rshift__(self, val):
+		print "__rshift__ called"
+	def __rrshift__(self, val):
+		print "__rrshift__ called"
+	def __irshift__(self, val):
+		print "__irshift__ called"
+		return self
+
+	def __lshift__(self, val):
+		print "__lshift__ called"
+	def __rlshift__(self, val):
+		print "__rlshift__ called"
+	def __ilshift__(self, val):
+		print "__ilshift__ called"
+		return self
+
+x = testall()
+x + 1
+1 + x
+x += 1
+
+x - 1
+1 - x
+x -= 1
+
+x * 1
+1 * x
+x *= 1
+
+x / 1
+1 / x
+x /= 1
+
+x % 1
+1 % x
+x %= 1
+
+x ** 1
+1 ** x
+x **= 1
+
+x | 1
+1 | x
+x |= 1
+
+x & 1
+1 & x
+x &= 1
+
+x ^ 1
+1 ^ x
+x ^= 1
+
+x >> 1
+1 >> x
+x >>= 1
+
+x << 1
+1 << x
+x <<= 1
+
diff --git a/Lib/dos-8x3/test_cla.py b/Lib/dos-8x3/test_cla.py
new file mode 100644
index 0000000..1fc9971
--- /dev/null
+++ b/Lib/dos-8x3/test_cla.py
@@ -0,0 +1,219 @@
+"Test the functionality of Python classes implementing operators."
+
+
+testmeths = [
+
+# Binary operations
+    "add",
+    "radd",
+    "sub",
+    "rsub",
+    "mul",
+    "rmul",
+    "div",
+    "rdiv",
+    "mod",
+    "rmod",
+    "divmod",
+    "rdivmod",
+    "pow",
+    "rpow",
+    "rshift",
+    "rrshift",
+    "lshift",
+    "rlshift",
+    "and",
+    "rand",
+    "or",
+    "ror",
+    "xor",
+    "rxor",
+
+# List/dict operations
+    "contains",
+    "getitem",
+    "getslice",
+    "setitem",
+    "setslice",
+    "delitem",
+    "delslice",
+
+# Unary operations
+    "neg",
+    "pos",
+    "abs",
+    "int",
+    "long",
+    "float",
+    "oct",
+    "hex",
+
+# generic operations
+    "init",
+    "del",
+    ]
+
+# These need to return something other than None
+#    "coerce",
+#    "hash",
+#    "str",
+#    "repr",
+
+# These are separate because they can influence the test of other methods.
+#    "getattr",
+#    "setattr",
+#    "delattr",
+
+class AllTests:
+    def __coerce__(self, *args):
+        print "__coerce__:", args
+        return (self,) + args 
+
+    def __hash__(self, *args):
+        print "__hash__:", args
+        return id(self)
+
+    def __str__(self, *args):
+        print "__str__:", args
+        return "AllTests"
+
+    def __repr__(self, *args):
+        print "__repr__:", args
+        return "AllTests"
+
+    def __cmp__(self, *args):
+        print "__cmp__:", args
+        return 0
+
+for method in testmeths:
+    exec("""def __%(method)s__(self, *args):
+                print "__%(method)s__:", args
+"""%locals(), AllTests.__dict__);
+
+# this also tests __init__ of course.
+testme = AllTests()
+
+# Binary operations
+
+testme + 1
+1 + testme
+
+testme - 1
+1 - testme
+
+testme * 1
+1 * testme
+
+testme / 1
+1 / testme
+
+testme % 1
+1 % testme
+
+divmod(testme,1)
+divmod(1, testme)
+
+testme ** 1
+1 ** testme
+
+testme >> 1
+1 >> testme
+
+testme << 1
+1 << testme
+
+testme & 1
+1 & testme
+
+testme | 1
+1 | testme
+
+testme ^ 1
+1 ^ testme
+
+
+# List/dict operations
+
+1 in testme
+
+testme[1]
+testme[1] = 1
+del testme[1]
+
+testme[:42]
+testme[:42] = "The Answer"
+del testme[:42]
+
+testme[2:1024:10]
+testme[2:1024:10] = "A lot"
+del testme[2:1024:10]
+
+testme[:42, ..., :24:, 24, 100]
+testme[:42, ..., :24:, 24, 100] = "Strange"
+del testme[:42, ..., :24:, 24, 100]
+
+
+# Now remove the slice hooks to see if converting normal slices to slice
+# object works.
+
+del AllTests.__getslice__
+del AllTests.__setslice__
+del AllTests.__delslice__
+
+testme[:42]
+testme[:42] = "The Answer"
+del testme[:42]
+
+
+# Unary operations
+
+-testme
++testme
+abs(testme)
+int(testme)
+long(testme)
+float(testme)
+oct(testme)
+hex(testme)
+
+
+# And the rest...
+
+hash(testme)
+repr(testme)
+str(testme)
+
+testme == 1
+testme < 1
+testme > 1
+testme <> 1
+testme != 1
+1 == testme
+1 < testme
+1 > testme
+1 <> testme
+1 != testme
+
+# This test has to be last (duh.)
+
+del testme
+
+
+# Interfering tests
+
+class ExtraTests:
+	def __getattr__(self, *args):
+		print "__getattr__:", args
+		return "SomeVal"
+
+	def __setattr__(self, *args):
+		print "__setattr__:", args
+
+	def __delattr__(self, *args):
+		print "__delattr__:", args
+
+testme = ExtraTests()
+testme.spam
+testme.eggs = "spam, spam, spam and ham"
+del testme.cardinal
+
diff --git a/Lib/dos-8x3/test_com.py b/Lib/dos-8x3/test_com.py
new file mode 100644
index 0000000..8905864
--- /dev/null
+++ b/Lib/dos-8x3/test_com.py
@@ -0,0 +1,16 @@
+from test_support import verbose, TestFailed
+
+if verbose:
+    print 'Running test on duplicate arguments'
+
+try:
+    exec('def f(a, a): pass')
+    raise TestFailed, "duplicate arguments"
+except SyntaxError:
+    pass
+
+try:
+    exec('def f(a = 0, a = 1): pass')
+    raise TestFailed, "duplicate keyword arguments"
+except SyntaxError:
+    pass
diff --git a/Lib/dos-8x3/test_coo.py b/Lib/dos-8x3/test_coo.py
new file mode 100644
index 0000000..a275cf2
--- /dev/null
+++ b/Lib/dos-8x3/test_coo.py
@@ -0,0 +1,40 @@
+
+# Simple test suite for Cookie.py
+
+import Cookie
+
+# Currently this only tests SimpleCookie
+
+cases = [
+    ('chips=ahoy; vienna=finger', {'chips':'ahoy', 'vienna':'finger'}),
+    ('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;";',
+     {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}),    
+    ] 
+
+for data, dict in cases:
+    C = Cookie.SimpleCookie() ; C.load(data)
+    print repr(C)
+    print str(C)
+    for k, v in dict.items():
+        print ' ', k, repr( C[k].value ), repr(v)
+        assert C[k].value == v
+        print C[k]
+
+C = Cookie.SimpleCookie()
+C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
+
+assert C['Customer'].value == 'WILE_E_COYOTE'
+assert C['Customer']['version'] == '1'
+assert C['Customer']['path'] == '/acme'
+
+print C.output(['path'])
+print C.js_output()
+print C.js_output(['path'])
+
+# Try cookie with quoted meta-data
+C = Cookie.SimpleCookie()
+C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+assert C['Customer'].value == 'WILE_E_COYOTE'
+assert C['Customer']['version'] == '1'
+assert C['Customer']['path'] == '/acme'
+
diff --git a/Lib/dos-8x3/test_dos.py b/Lib/dos-8x3/test_dos.py
new file mode 100644
index 0000000..ffa3ef7
--- /dev/null
+++ b/Lib/dos-8x3/test_dos.py
@@ -0,0 +1,49 @@
+import dospath
+import string
+import os
+
+errors = 0
+
+def tester(fn, wantResult):
+	fn = string.replace(fn, "\\", "\\\\")
+	gotResult = eval(fn)
+	if wantResult != gotResult:
+		print "error!"
+		print "evaluated: " + str(fn)
+		print "should be: " + str(wantResult)
+		print " returned: " + str(gotResult)
+		print ""
+		global errors
+		errors = errors + 1
+
+tester('dospath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar'))
+tester('dospath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar'))
+
+tester('dospath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
+tester('dospath.split("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint\\foo', 'bar'))
+
+tester('dospath.split("c:\\")', ('c:\\', ''))
+tester('dospath.split("\\\\conky\\mountpoint\\")', ('\\\\conky\\mountpoint', ''))
+
+tester('dospath.split("c:/")', ('c:/', ''))
+tester('dospath.split("//conky/mountpoint/")', ('//conky/mountpoint', ''))
+
+tester('dospath.isabs("c:\\")', 1)
+tester('dospath.isabs("\\\\conky\\mountpoint\\")', 1)
+tester('dospath.isabs("\\foo")', 1)
+tester('dospath.isabs("\\foo\\bar")', 1)
+
+tester('dospath.abspath("C:\\")', "C:\\")
+
+tester('dospath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
+       "/home/swen")
+tester('dospath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
+       "\\home\\swen\\")
+tester('dospath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
+       "/home/swen/spam")
+
+if errors:
+	print str(errors) + " errors."
+else:
+	print "No errors.  Thank your lucky stars."
+
diff --git a/Lib/dos-8x3/test_fil.py b/Lib/dos-8x3/test_fil.py
new file mode 100644
index 0000000..4ad5c95
--- /dev/null
+++ b/Lib/dos-8x3/test_fil.py
@@ -0,0 +1,45 @@
+from test_support import TESTFN
+from UserList import UserList
+
+# verify writelines with instance sequence
+l = UserList(['1', '2'])
+f = open(TESTFN, 'wb')
+f.writelines(l)
+f.close()
+f = open(TESTFN, 'rb')
+buf = f.read()
+f.close()
+assert buf == '12'
+
+# verify writelines with integers
+f = open(TESTFN, 'wb')
+try:
+    f.writelines([1, 2, 3])
+except TypeError:
+    pass
+else:
+    print "writelines accepted sequence of integers"
+f.close()
+
+# verify writelines with integers in UserList
+f = open(TESTFN, 'wb')
+l = UserList([1,2,3])
+try:
+    f.writelines(l)
+except TypeError:
+    pass
+else:
+    print "writelines accepted sequence of integers"
+f.close()
+
+# verify writelines with non-string object
+class NonString: pass
+
+f = open(TESTFN, 'wb')
+try:
+    f.writelines([NonString(), NonString()])
+except TypeError:
+    pass
+else:
+    print "writelines accepted sequence of non-string objects"
+f.close()
diff --git a/Lib/dos-8x3/test_get.py b/Lib/dos-8x3/test_get.py
new file mode 100644
index 0000000..3927c1c
--- /dev/null
+++ b/Lib/dos-8x3/test_get.py
@@ -0,0 +1,101 @@
+# test_getopt.py
+# David Goodger <dgoodger@bigfoot.com> 2000-08-19
+
+import getopt
+from getopt import GetoptError
+from test_support import verbose
+
+def expectException(teststr, expected, failure=AssertionError):
+    """Executes a statement passed in teststr, and raises an exception
+       (failure) if the expected exception is *not* raised."""
+    try:
+        exec teststr
+    except expected:
+        pass
+    else:
+        raise failure
+
+if verbose:
+    print 'Running tests on getopt.short_has_arg'
+assert getopt.short_has_arg('a', 'a:')
+assert not getopt.short_has_arg('a', 'a')
+expectException("tmp = getopt.short_has_arg('a', 'b')", GetoptError)
+expectException("tmp = getopt.short_has_arg('a', '')", GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.long_has_args'
+has_arg, option = getopt.long_has_args('abc', ['abc='])
+assert has_arg
+assert option == 'abc'
+has_arg, option = getopt.long_has_args('abc', ['abc'])
+assert not has_arg
+assert option == 'abc'
+has_arg, option = getopt.long_has_args('abc', ['abcd'])
+assert not has_arg
+assert option == 'abcd'
+expectException("has_arg, option = getopt.long_has_args('abc', ['def'])",
+                GetoptError)
+expectException("has_arg, option = getopt.long_has_args('abc', [])",
+                GetoptError)
+expectException("has_arg, option = " + \
+                     "getopt.long_has_args('abc', ['abcd','abcde'])",
+                GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.do_shorts'
+opts, args = getopt.do_shorts([], 'a', 'a', [])
+assert opts == [('-a', '')]
+assert args == []
+opts, args = getopt.do_shorts([], 'a1', 'a:', [])
+assert opts == [('-a', '1')]
+assert args == []
+#opts, args = getopt.do_shorts([], 'a=1', 'a:', [])
+#assert opts == [('-a', '1')]
+#assert args == []
+opts, args = getopt.do_shorts([], 'a', 'a:', ['1'])
+assert opts == [('-a', '1')]
+assert args == []
+opts, args = getopt.do_shorts([], 'a', 'a:', ['1', '2'])
+assert opts == [('-a', '1')]
+assert args == ['2']
+expectException("opts, args = getopt.do_shorts([], 'a1', 'a', [])",
+                GetoptError)
+expectException("opts, args = getopt.do_shorts([], 'a', 'a:', [])",
+                GetoptError)
+
+if verbose:
+    print 'Running tests on getopt.do_longs'
+opts, args = getopt.do_longs([], 'abc', ['abc'], [])
+assert opts == [('--abc', '')]
+assert args == []
+opts, args = getopt.do_longs([], 'abc=1', ['abc='], [])
+assert opts == [('--abc', '1')]
+assert args == []
+opts, args = getopt.do_longs([], 'abc=1', ['abcd='], [])
+assert opts == [('--abcd', '1')]
+assert args == []
+expectException("opts, args = getopt.do_longs([], 'abc=1', ['abc'], [])",
+                GetoptError)
+expectException("opts, args = getopt.do_longs([], 'abc', ['abc='], [])",
+                GetoptError)
+
+# note: the empty string between '-a' and '--beta' is significant:
+# it simulates an empty string option argument ('-a ""') on the command line.
+cmdline = ['-a', '1', '-b', '--alpha=2', '--beta', '-a', '3', '-a', '',
+           '--beta', 'arg1', 'arg2']
+
+if verbose:
+    print 'Running tests on getopt.getopt'
+opts, args = getopt.getopt(cmdline, 'a:b', ['alpha=', 'beta'])
+assert opts == [('-a', '1'), ('-b', ''), ('--alpha', '2'), ('--beta', ''),
+                ('-a', '3'), ('-a', ''), ('--beta', '')]
+# Note ambiguity of ('-b', '') and ('-a', '') above. This must be
+# accounted for in the code that calls getopt().
+assert args == ['arg1', 'arg2']
+
+expectException(
+    "opts, args = getopt.getopt(cmdline, 'a:b', ['alpha', 'beta'])",
+    GetoptError)
+
+if verbose:
+    print "Module getopt: tests completed successfully."
diff --git a/Lib/dos-8x3/test_lar.py b/Lib/dos-8x3/test_lar.py
new file mode 100644
index 0000000..5b65237
--- /dev/null
+++ b/Lib/dos-8x3/test_lar.py
@@ -0,0 +1,129 @@
+#!python
+
+#----------------------------------------------------------------------
+# test largefile support on system where this makes sense
+#
+#XXX how to only run this when support is there
+#XXX how to only optionally run this, it will take along time
+#----------------------------------------------------------------------
+
+import test_support
+import os, struct, stat, sys
+
+
+# only run if the current system support large files
+f = open(test_support.TESTFN, 'w')
+try:
+	# 2**31 == 2147483648
+	f.seek(2147483649L)
+except OverflowError:
+	raise test_support.TestSkipped, "platform does not have largefile support"
+else:
+	f.close()
+
+
+# create >2GB file (2GB = 2147483648 bytes)
+size = 2500000000L
+name = test_support.TESTFN
+
+
+# on Windows this test comsumes large resources:
+#  it takes a long time to build the >2GB file and takes >2GB of disk space
+# therefore test_support.use_large_resources must be defined to run this test
+if sys.platform[:3] == 'win' and not test_support.use_large_resources:
+	raise test_support.TestSkipped, \
+		"test requires %s bytes and a long time to run" % str(size)
+
+
+
+def expect(got_this, expect_this):
+	if test_support.verbose:
+		print '%s =?= %s ...' % (`got_this`, `expect_this`),
+	if got_this != expect_this:
+		if test_support.verbose:
+			print 'no'
+		raise test_support.TestFailed, 'got %s, but expected %s' %\
+			(str(got_this), str(expect_this))
+	else:
+		if test_support.verbose:
+			print 'yes'
+
+
+# test that each file function works as expected for a large (i.e. >2GB, do
+# we have to check >4GB) files
+
+if test_support.verbose:
+	print 'create large file via seek (may be sparse file) ...'
+f = open(name, 'w')
+f.seek(size)
+f.write('a')
+f.flush()
+expect(os.fstat(f.fileno())[stat.ST_SIZE], size+1)
+if test_support.verbose:
+	print 'check file size with os.fstat'
+f.close()
+if test_support.verbose:
+	print 'check file size with os.stat'
+expect(os.stat(name)[stat.ST_SIZE], size+1)
+
+if test_support.verbose:
+	print 'play around with seek() and read() with the built largefile'
+f = open(name, 'r')
+expect(f.tell(), 0)
+expect(f.read(1), '\000')
+expect(f.tell(), 1)
+f.seek(0)
+expect(f.tell(), 0)
+f.seek(0, 0)
+expect(f.tell(), 0)
+f.seek(42)
+expect(f.tell(), 42)
+f.seek(42, 0)
+expect(f.tell(), 42)
+f.seek(42, 1)
+expect(f.tell(), 84)
+f.seek(0, 1)
+expect(f.tell(), 84)
+f.seek(0, 2) # seek from the end
+expect(f.tell(), size + 1 + 0)
+f.seek(-10, 2)
+expect(f.tell(), size + 1 - 10)
+f.seek(-size-1, 2)
+expect(f.tell(), 0)
+f.seek(size)
+expect(f.tell(), size)
+expect(f.read(1), 'a') # the 'a' that was written at the end of the file above
+f.close()
+
+if test_support.verbose:
+	print 'play around with os.lseek() with the built largefile'
+f = open(name, 'r')
+expect(os.lseek(f.fileno(), 0, 0), 0)
+expect(os.lseek(f.fileno(), 42, 0), 42)
+expect(os.lseek(f.fileno(), 42, 1), 84)
+expect(os.lseek(f.fileno(), 0, 1), 84)
+expect(os.lseek(f.fileno(), 0, 2), size+1+0)
+expect(os.lseek(f.fileno(), -10, 2), size+1-10)
+expect(os.lseek(f.fileno(), -size-1, 2), 0)
+expect(os.lseek(f.fileno(), size, 0), size)
+expect(f.read(1), 'a') # the 'a' that was written at the end of the file above
+f.close()
+
+
+# XXX add tests for truncate if it exists
+# XXX has truncate ever worked on Windows? specifically on WinNT I get:
+#     "IOError: [Errno 13] Permission denied"
+##try:
+##	newsize = size - 10
+##	f.seek(newsize)
+##	f.truncate()
+##	expect(f.tell(), newsize)
+##	newsize = newsize - 1
+##	f.seek(0)
+##	f.truncate(newsize)
+##	expect(f.tell(), newsize)
+##except AttributeError:
+##	pass
+
+os.unlink(name)
+
diff --git a/Lib/dos-8x3/test_min.py b/Lib/dos-8x3/test_min.py
new file mode 100644
index 0000000..73c8ac4
--- /dev/null
+++ b/Lib/dos-8x3/test_min.py
@@ -0,0 +1,331 @@
+# test for xml.dom.minidom
+
+from xml.dom.minidom import parse, Node, Document, parseString
+
+import os.path
+import sys
+import traceback
+
+if __name__ == "__main__":
+    base = sys.argv[0]
+else:
+    base = __file__
+tstfile = os.path.join(os.path.dirname(base), "test.xml")
+del base
+
+Node._debug=1
+
+def testGetElementsByTagName( ):
+    dom=parse( tstfile )
+    assert dom.getElementsByTagName( "LI" )==\
+            dom.documentElement.getElementsByTagName( "LI" )
+    dom.unlink()
+    dom=None
+    assert( len( Node.allnodes ))==0
+
+def testInsertBefore( ):
+    dom=parse( tstfile )
+    docel=dom.documentElement
+    #docel.insertBefore( dom.createProcessingInstruction("a", "b"),
+    #                        docel.childNodes[1])
+                            
+    #docel.insertBefore( dom.createProcessingInstruction("a", "b"),
+    #                        docel.childNodes[0])
+
+    #assert docel.childNodes[0].target=="a"
+    #assert docel.childNodes[2].target=="a"
+    dom.unlink()
+    del dom
+    del docel
+    assert( len( Node.allnodes ))==0
+
+def testAppendChild():
+    dom=parse( tstfile )
+    dom.documentElement.appendChild( dom.createComment( u"Hello" ))
+    assert dom.documentElement.childNodes[-1].nodeName=="#comment"
+    assert dom.documentElement.childNodes[-1].data=="Hello"
+    dom.unlink()
+    dom=None
+    assert( len( Node.allnodes ))==0
+
+def testNonZero():
+    dom=parse( tstfile )
+    assert dom # should not be zero
+    dom.appendChild( dom.createComment( "foo" ) )
+    assert not dom.childNodes[-1].childNodes
+    dom.unlink()
+    dom=None
+    assert( len( Node.allnodes ))==0
+
+def testUnlink():
+    dom=parse( tstfile )
+    dom.unlink()
+    dom=None
+    assert( len( Node.allnodes ))==0
+
+def testElement():
+    dom=Document()
+    dom.appendChild( dom.createElement( "abc" ) )
+    assert dom.documentElement
+    dom.unlink()
+    dom=None
+    assert( 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/>" )
+    el=dom.documentElement
+    el.setAttribute( "spam", "jam" )
+    el.setAttribute( "spam", "jam2" )
+    dom.unlink()
+    dom=None
+
+def testAddAttr():
+    dom=Document()
+    child=dom.appendChild( dom.createElement( "abc" ) )
+
+    child.setAttribute( "def", "ghi" )
+    assert child.getAttribute( "def" )=="ghi"
+    assert child.attributes["def"].value=="ghi"
+
+    child.setAttribute( "jkl", "mno" )
+    assert child.getAttribute( "jkl" )=="mno"
+    assert child.attributes["jkl"].value=="mno"
+
+    assert len( child.attributes )==2
+
+    child.setAttribute( "def", "newval" )
+    assert child.getAttribute( "def" )=="newval"
+    assert child.attributes["def"].value=="newval"
+
+    assert len( child.attributes )==2
+
+    dom.unlink()
+    dom=None
+    child=None
+
+def testDeleteAttr():
+    dom=Document()
+    child=dom.appendChild( dom.createElement( "abc" ) )
+
+    assert len( child.attributes)==0
+    child.setAttribute( "def", "ghi" )
+    assert len( child.attributes)==1
+    del child.attributes["def"]
+    assert len( child.attributes)==0
+    dom.unlink()
+    assert( len( Node.allnodes ))==0
+
+def testRemoveAttr():
+    dom=Document()
+    child=dom.appendChild( dom.createElement( "abc" ) )
+
+    child.setAttribute( "def", "ghi" )
+    assert len( child.attributes)==1
+    child.removeAttribute("def" )
+    assert len( child.attributes)==0
+
+    dom.unlink()
+
+def testRemoveAttrNS():
+    dom=Document()
+    child=dom.appendChild( 
+            dom.createElementNS( "http://www.python.org", "python:abc" ) )
+    child.setAttributeNS( "http://www.w3.org", "xmlns:python", 
+                                            "http://www.python.org" )
+    child.setAttributeNS( "http://www.python.org", "python:abcattr", "foo" )
+    assert len( child.attributes )==2
+    child.removeAttributeNS( "http://www.python.org", "abcattr" )
+    assert len( child.attributes )==1
+
+    dom.unlink()
+    dom=None
+    
+def testRemoveAttributeNode():
+    dom=Document()
+    child=dom.appendChild( dom.createElement( "foo" ) )
+    child.setAttribute( "spam", "jam" )
+    assert len( child.attributes )==1
+    node=child.getAttributeNode( "spam" )
+    child.removeAttributeNode( node )
+    assert len( child.attributes )==0
+
+    dom.unlink()
+    dom=None
+    assert len( Node.allnodes )==0
+
+def testChangeAttr():
+    dom=parseString( "<abc/>" )
+    el=dom.documentElement
+    el.setAttribute( "spam", "jam" )
+    assert len( el.attributes )==1
+    el.setAttribute( "spam", "bam" )
+    assert len( el.attributes )==1
+    el.attributes["spam"]="ham"
+    assert len( el.attributes )==1
+    el.setAttribute( "spam2", "bam" )
+    assert len( el.attributes )==2
+    el.attributes[ "spam2"]= "bam2"
+    assert len( el.attributes )==2
+    dom.unlink()
+    dom=None
+    assert len( Node.allnodes )==0
+
+def testGetAttrList():
+    pass
+
+def testGetAttrValues(): pass
+
+def testGetAttrLength(): pass
+
+def testGetAttribute(): pass
+
+def testGetAttributeNS(): pass
+
+def testGetAttributeNode(): pass
+
+def testGetElementsByTagNameNS(): pass
+
+def testGetEmptyNodeListFromElementsByTagNameNS(): pass
+
+def testElementReprAndStr():
+    dom=Document()
+    el=dom.appendChild( dom.createElement( "abc" ) )
+    string1=repr( el )
+    string2=str( el )
+    assert string1==string2
+    dom.unlink()
+
+# commented out until Fredrick's fix is checked in
+def _testElementReprAndStrUnicode():
+    dom=Document()
+    el=dom.appendChild( dom.createElement( u"abc" ) )
+    string1=repr( el )
+    string2=str( el )
+    assert string1==string2
+    dom.unlink()
+
+# commented out until Fredrick's fix is checked in
+def _testElementReprAndStrUnicodeNS():
+    dom=Document()
+    el=dom.appendChild(
+	 dom.createElementNS( u"http://www.slashdot.org", u"slash:abc" ))
+    string1=repr( el )
+    string2=str( el )
+    assert string1==string2
+    assert string1.find("slash:abc" )!=-1
+    dom.unlink()
+
+def testAttributeRepr():
+    dom=Document()
+    el=dom.appendChild( dom.createElement( u"abc" ) )
+    node=el.setAttribute( "abc", "def" )
+    assert str( node ) == repr( node )
+    dom.unlink()
+
+def testTextNodeRepr(): pass
+
+def testWriteXML(): pass
+
+def testProcessingInstruction(): pass
+
+def testProcessingInstructionRepr(): pass
+
+def testTextRepr(): pass
+
+def testWriteText(): pass
+
+def testDocumentElement(): pass
+
+def testTooManyDocumentElements(): pass
+
+def testCreateElementNS(): pass
+
+def testCreatAttributeNS(): pass
+
+def testParse(): pass
+
+def testParseString(): pass
+
+def testComment(): pass
+
+def testAttrListItem(): pass
+
+def testAttrListItems(): pass
+
+def testAttrListItemNS(): pass
+
+def testAttrListKeys(): pass
+
+def testAttrListKeysNS(): pass
+
+def testAttrListValues(): pass
+
+def testAttrListLength(): pass
+
+def testAttrList__getitem__(): pass
+
+def testAttrList__setitem__(): pass
+
+def testSetAttrValueandNodeValue(): pass
+
+def testParseElement(): pass
+
+def testParseAttributes(): pass
+
+def testParseElementNamespaces(): pass
+
+def testParseAttributeNamespaces(): pass
+
+def testParseProcessingInstructions(): pass
+
+def testChildNodes(): pass
+
+def testFirstChild(): pass
+
+def testHasChildNodes(): pass
+
+def testCloneElementShallow(): pass
+
+def testCloneElementShallowCopiesAttributes(): pass
+
+def testCloneElementDeep(): pass
+
+def testCloneDocumentShallow(): pass
+
+def testCloneDocumentDeep(): pass
+
+def testCloneAttributeShallow(): pass
+
+def testCloneAttributeDeep(): pass
+
+def testClonePIShallow(): pass
+
+def testClonePIDeep(): pass
+
+
+names=globals().keys()
+names.sort()
+for name in names:
+    if name.startswith( "test" ):
+        func=globals()[name]
+        try:
+            func()
+            print "Test Succeeded", name
+            if len( Node.allnodes ):
+                print "Garbage left over:"
+                print Node.allnodes.items()[0:10]
+            Node.allnodes={}
+        except Exception, e :
+            print "Test Failed: ", name
+            apply( traceback.print_exception, sys.exc_info() )
+            print `e`
+            Node.allnodes={}
+            raise
+
diff --git a/Lib/dos-8x3/test_par.py b/Lib/dos-8x3/test_par.py
new file mode 100644
index 0000000..bc41de4
--- /dev/null
+++ b/Lib/dos-8x3/test_par.py
@@ -0,0 +1,178 @@
+import os.path
+import parser
+import pprint
+import sys
+
+from parser import expr, suite, sequence2ast
+from test_support import verbose
+
+#
+#  First, we test that we can generate trees from valid source fragments,
+#  and that these valid trees are indeed allowed by the tree-loading side
+#  of the parser module.
+#
+
+def roundtrip(f, s):
+    st1 = f(s)
+    t = st1.totuple()
+    st2 = parser.sequence2ast(t)
+
+def roundtrip_fromfile(filename):
+    roundtrip(suite, open(filename).read())
+
+def test_expr(s):
+    print "expr:", s
+    roundtrip(expr, s)
+
+def test_suite(s):
+    print "suite:", s
+    roundtrip(suite, s)
+
+
+print "Expressions:"
+
+test_expr("foo(1)")
+test_expr("[1, 2, 3]")
+test_expr("[x**3 for x in range(20)]")
+test_expr("[x**3 for x in range(20) if x % 3]")
+test_expr("foo(*args)")
+test_expr("foo(*args, **kw)")
+test_expr("foo(**kw)")
+test_expr("foo(key=value)")
+test_expr("foo(key=value, *args)")
+test_expr("foo(key=value, *args, **kw)")
+test_expr("foo(key=value, **kw)")
+test_expr("foo(a, b, c, *args)")
+test_expr("foo(a, b, c, *args, **kw)")
+test_expr("foo(a, b, c, **kw)")
+test_expr("foo + bar")
+
+print
+print "Statements:"
+test_suite("print")
+test_suite("print 1")
+test_suite("print 1,")
+test_suite("print >>fp")
+test_suite("print >>fp, 1")
+test_suite("print >>fp, 1,")
+
+# expr_stmt
+test_suite("a")
+test_suite("a = b")
+test_suite("a = b = c = d = e")
+test_suite("a += b")
+test_suite("a -= b")
+test_suite("a *= b")
+test_suite("a /= b")
+test_suite("a %= b")
+test_suite("a &= b")
+test_suite("a |= b")
+test_suite("a ^= b")
+test_suite("a <<= b")
+test_suite("a >>= b")
+test_suite("a **= b")
+
+#d = os.path.dirname(os.__file__)
+#roundtrip_fromfile(os.path.join(d, "os.py"))
+#roundtrip_fromfile(os.path.join(d, "test", "test_parser.py"))
+
+#
+#  Second, we take *invalid* trees and make sure we get ParserError
+#  rejections for them.
+#
+
+print
+print "Invalid parse trees:"
+
+def check_bad_tree(tree, label):
+    print
+    print label
+    try:
+        sequence2ast(tree)
+    except parser.ParserError:
+        print "caught expected exception for invalid tree"
+        pass
+    else:
+        print "test failed: did not properly detect invalid tree:"
+        pprint.pprint(tree)
+
+
+# not even remotely valid:
+check_bad_tree((1, 2, 3), "<junk>")
+
+# print >>fp,
+tree = \
+(257,
+ (264,
+  (265,
+   (266,
+    (268,
+     (1, 'print'),
+     (35, '>>'),
+     (290,
+      (291,
+       (292,
+        (293,
+         (295,
+          (296,
+           (297,
+            (298, (299, (300, (301, (302, (303, (1, 'fp')))))))))))))),
+     (12, ','))),
+   (4, ''))),
+ (0, ''))
+
+check_bad_tree(tree, "print >>fp,")
+
+# a,,c
+tree = \
+(258,
+ (311,
+  (290,
+   (291,
+    (292,
+     (293,
+      (295,
+       (296, (297, (298, (299, (300, (301, (302, (303, (1, 'a')))))))))))))),
+  (12, ','),
+  (12, ','),
+  (290,
+   (291,
+    (292,
+     (293,
+      (295,
+       (296, (297, (298, (299, (300, (301, (302, (303, (1, 'c'))))))))))))))),
+ (4, ''),
+ (0, ''))
+
+check_bad_tree(tree, "a,,c")
+
+# a $= b
+tree = \
+(257,
+ (264,
+  (265,
+   (266,
+    (267,
+     (312,
+      (291,
+       (292,
+        (293,
+         (294,
+          (296,
+           (297,
+            (298,
+             (299, (300, (301, (302, (303, (304, (1, 'a'))))))))))))))),
+     (268, (37, '$=')),
+     (312,
+      (291,
+       (292,
+        (293,
+         (294,
+          (296,
+           (297,
+            (298,
+             (299, (300, (301, (302, (303, (304, (1, 'b'))))))))))))))))),
+   (4, ''))),
+ (0, ''))
+
+check_bad_tree(tree, "a $= b")
diff --git a/Lib/dos-8x3/test_pol.py b/Lib/dos-8x3/test_pol.py
new file mode 100644
index 0000000..82d8372
--- /dev/null
+++ b/Lib/dos-8x3/test_pol.py
@@ -0,0 +1,172 @@
+# Test case for the os.poll() function
+    
+import sys, os, select, random
+from test_support import verbose, TestSkipped, TESTFN
+
+try:
+    select.poll
+except AttributeError:
+    raise TestSkipped, "select.poll not defined -- skipping test_poll"
+
+
+def find_ready_matching(ready, flag):
+    match = []
+    for fd, mode in ready:
+        if mode & flag:
+            match.append(fd)
+    return match
+
+def test_poll1():
+    """Basic functional test of poll object
+
+    Create a bunch of pipe and test that poll works with them.
+    """
+    print 'Running poll test 1'
+    p = select.poll()
+
+    NUM_PIPES = 12
+    MSG = " This is a test."
+    MSG_LEN = len(MSG)
+    readers = []
+    writers = []
+    r2w = {}
+    w2r = {}
+
+    for i in range(NUM_PIPES):
+        rd, wr = os.pipe()
+        p.register(rd, select.POLLIN)
+        p.register(wr, select.POLLOUT)
+        readers.append(rd)
+        writers.append(wr)
+        r2w[rd] = wr
+        w2r[wr] = rd
+
+    while writers:
+        ready = p.poll()
+        ready_writers = find_ready_matching(ready, select.POLLOUT)
+        if not ready_writers:
+            raise RuntimeError, "no pipes ready for writing"
+        wr = random.choice(ready_writers)
+        os.write(wr, MSG)
+
+        ready = p.poll()
+        ready_readers = find_ready_matching(ready, select.POLLIN)
+        if not ready_readers:
+            raise RuntimeError, "no pipes ready for reading"
+        rd = random.choice(ready_readers)
+        buf = os.read(rd, MSG_LEN)
+        assert len(buf) == MSG_LEN
+        print buf
+        os.close(r2w[rd]) ; os.close( rd )
+        p.unregister( r2w[rd] )
+        p.unregister( rd )
+        writers.remove(r2w[rd])
+
+    poll_unit_tests()
+    print 'Poll test 1 complete'
+
+def poll_unit_tests():
+    # returns NVAL for invalid file descriptor
+    FD = 42
+    try:
+        os.close(FD)
+    except OSError:
+        pass
+    p = select.poll()
+    p.register(FD)
+    r = p.poll()
+    assert r[0] == (FD, select.POLLNVAL)
+
+    f = open(TESTFN, 'w')
+    fd = f.fileno()
+    p = select.poll()
+    p.register(f)
+    r = p.poll()
+    assert r[0][0] == fd
+    f.close()
+    r = p.poll()
+    assert r[0] == (fd, select.POLLNVAL)
+    os.unlink(TESTFN)
+
+    # type error for invalid arguments
+    p = select.poll()
+    try:
+        p.register(p)
+    except TypeError:
+        pass
+    else:
+        print "Bogus register call did not raise TypeError"
+    try:
+        p.unregister(p)
+    except TypeError:
+        pass
+    else:
+        print "Bogus unregister call did not raise TypeError"
+
+    # can't unregister non-existent object
+    p = select.poll()
+    try:
+        p.unregister(3)
+    except KeyError:
+        pass
+    else:
+        print "Bogus unregister call did not raise KeyError"
+
+    # Test error cases
+    pollster = select.poll()
+    class Nope:
+        pass
+
+    class Almost:
+        def fileno(self):
+            return 'fileno'
+
+    try:
+        pollster.register( Nope(), 0 )
+    except TypeError: pass
+    else: print 'expected TypeError exception, not raised'
+
+    try:
+        pollster.register( Almost(), 0 )
+    except TypeError: pass
+    else: print 'expected TypeError exception, not raised'
+
+
+# Another test case for poll().  This is copied from the test case for
+# select(), modified to use poll() instead.
+
+def test_poll2():
+    print 'Running poll test 2'
+    cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
+    p = os.popen(cmd, 'r')
+    pollster = select.poll()
+    pollster.register( p, select.POLLIN )
+    for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
+        if verbose:
+            print 'timeout =', tout
+        fdlist = pollster.poll(tout)
+        if (fdlist == []):
+            continue
+        fd, flags = fdlist[0]
+        if flags & select.POLLHUP:
+            line = p.readline()
+            if line != "":
+                print 'error: pipe seems to be closed, but still returns data'
+            continue
+
+        elif flags & select.POLLIN:
+            line = p.readline()
+            if verbose:
+                print `line`
+            if not line:
+                if verbose:
+                    print 'EOF'
+                break
+            continue
+        else:
+            print 'Unexpected return value from select.poll:', fdlist
+    p.close()
+    print 'Poll test 2 complete'
+
+test_poll1()
+test_poll2()
diff --git a/Lib/dos-8x3/test_pos.py b/Lib/dos-8x3/test_pos.py
new file mode 100644
index 0000000..27bee61
--- /dev/null
+++ b/Lib/dos-8x3/test_pos.py
@@ -0,0 +1,42 @@
+import posixpath
+import string
+
+errors = 0
+
+def tester(fn, wantResult):
+	gotResult = eval(fn)
+	if wantResult != gotResult:
+		print "error!"
+		print "evaluated: " + str(fn)
+		print "should be: " + str(wantResult)
+		print " returned: " + str(gotResult)
+		print ""
+		global errors
+		errors = errors + 1
+
+tester('posixpath.splitdrive("/foo/bar")', ('', '/foo/bar'))
+
+tester('posixpath.split("/foo/bar")', ('/foo', 'bar'))
+tester('posixpath.split("/")', ('/', ''))
+tester('posixpath.split("foo")', ('', 'foo'))
+
+tester('posixpath.splitext("foo.ext")', ('foo', '.ext'))
+tester('posixpath.splitext("/foo/foo.ext")', ('/foo/foo', '.ext'))
+
+tester('posixpath.isabs("/")', 1)
+tester('posixpath.isabs("/foo")', 1)
+tester('posixpath.isabs("/foo/bar")', 1)
+tester('posixpath.isabs("foo/bar")', 0)
+
+tester('posixpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
+       "/home/swen")
+tester('posixpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"])',
+       "/home/swen/")
+tester('posixpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
+       "/home/swen/spam")
+
+if errors:
+	print str(errors) + " errors."
+else:
+	print "No errors.  Thank your lucky stars."
+
diff --git a/Lib/dos-8x3/test_url.py b/Lib/dos-8x3/test_url.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Lib/dos-8x3/test_url.py
diff --git a/Lib/dos-8x3/threadst.py b/Lib/dos-8x3/threadst.py
deleted file mode 100644
index d9c2788..0000000
--- a/Lib/dos-8x3/threadst.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import thread
-# Start empty thread to initialize thread mechanics (and global lock!)
-# This thread will finish immediately thus won't make much influence on
-# test results by itself, only by that fact that it initializes global lock
-thread.start_new_thread(lambda : 1, ())
-
-import test.pystone
-test.pystone.main()
-
diff --git a/Lib/dos-8x3/webbrows.py b/Lib/dos-8x3/webbrows.py
new file mode 100644
index 0000000..5a4a80f
--- /dev/null
+++ b/Lib/dos-8x3/webbrows.py
@@ -0,0 +1,229 @@
+"""Remote-control interfaces to some browsers."""
+
+import os
+import sys
+
+
+PROCESS_CREATION_DELAY = 4
+
+
+class Error(Exception):
+    pass
+
+
+_browsers = {}
+
+def register(name, klass, instance=None):
+    """Register a browser connector and, optionally, connection."""
+    _browsers[name.lower()] = [klass, instance]
+
+
+def get(name=None):
+    """Retrieve a connection to a browser by type name, or the default
+    browser."""
+    name = name or DEFAULT_BROWSER
+    try:
+        L = _browsers[name.lower()]
+    except KeyError:
+        raise ValueError, "unknown browser type: " + `name`
+    if L[1] is None:
+        L[1] = L[0]()
+    return L[1]
+
+
+# Please note: the following definition hides a builtin function.
+
+def open(url, new=0):
+    get().open(url, new)
+
+
+def open_new(url):
+    get().open_new(url)
+
+
+def _iscommand(cmd):
+    """Return true if cmd can be found on the executable search path."""
+    path = os.environ.get("PATH")
+    if not path:
+        return 0
+    for d in path.split(os.pathsep):
+        exe = os.path.join(d, cmd)
+        if os.path.isfile(exe):
+            return 1
+    return 0
+
+
+class CommandLineBrowser:
+    _browsers = []
+    if os.environ.get("DISPLAY"):
+        _browsers.extend([
+            ("netscape", "netscape %s >/dev/null &"),
+            ("mosaic", "mosaic %s >/dev/null &"),
+            ])
+    _browsers.extend([
+        ("lynx", "lynx %s"),
+        ("w3m", "w3m %s"),
+        ])
+
+    def open(self, url, new=0):
+        for exe, cmd in self._browsers:
+            if _iscommand(exe):
+                os.system(cmd % url)
+                return
+        raise Error("could not locate runnable browser")
+
+    def open_new(self, url):
+        self.open(url)
+
+register("command-line", CommandLineBrowser)
+
+
+class Netscape:
+    autoRaise = 1
+
+    def _remote(self, action):
+        raise_opt = ("-noraise", "-raise")[self.autoRaise]
+        cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
+        rc = os.system(cmd)
+        if rc:
+            import time
+            os.system("netscape -no-about-splash &")
+            time.sleep(PROCESS_CREATION_DELAY)
+            rc = os.system(cmd)
+        return not rc
+
+    def open(self, url, new=0):
+        if new:
+            self.open_new(url)
+        else:
+            self._remote("openURL(%s)" % url)
+
+    def open_new(self, url):
+        self._remote("openURL(%s, new-window)" % url)
+
+register("netscape", Netscape)
+
+
+class Konquerer:
+    """Controller for the KDE File Manager (kfm, or Konquerer).
+
+    See http://developer.kde.org/documentation/other/kfmclient.html
+    for more information on the Konquerer remote-control interface.
+
+    """
+    def _remote(self, action):
+        cmd = "kfmclient %s >/dev/null 2>&1" % action
+        rc = os.system(cmd)
+        if rc:
+            import time
+            os.system("kfm -d &")
+            time.sleep(PROCESS_CREATION_DELAY)
+            rc = os.system(cmd)
+        return not rc
+
+    def open(self, url, new=1):
+	# XXX currently I know no way to prevent KFM from opening a new win.
+        self.open_new(url)
+
+    def open_new(self, url):
+        self._remote("openURL %s" % url)
+
+register("kfm", Konquerer)
+
+
+class Grail:
+    # There should be a way to maintain a connection to Grail, but the
+    # Grail remote control protocol doesn't really allow that at this
+    # point.  It probably never will!
+
+    def _find_grail_rc(self):
+        import glob
+        import pwd
+        import socket
+        import tempfile
+        tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
+        user = pwd.getpwuid(_os.getuid())[0]
+        filename = os.path.join(tempdir, user + "-*")
+        maybes = glob.glob(filename)
+        if not maybes:
+            return None
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        for fn in maybes:
+            # need to PING each one until we find one that's live
+            try:
+                s.connect(fn)
+            except socket.error:
+                # no good; attempt to clean it out, but don't fail:
+                try:
+                    os.unlink(fn)
+                except IOError:
+                    pass
+            else:
+                return s
+
+    def _remote(self, action):
+        s = self._find_grail_rc()
+        if not s:
+            return 0
+        s.send(action)
+        s.close()
+        return 1
+
+    def open(self, url, new=0):
+        if new:
+            self.open_new(url)
+        else:
+            self._remote("LOAD " + url)
+
+    def open_new(self, url):
+        self._remote("LOADNEW " + url)
+
+register("grail", Grail)
+
+
+class WindowsDefault:
+    def open(self, url, new=0):
+        import win32api, win32con
+        win32api.ShellExecute(0, "open", url, None, ".",
+                              win32con.SW_SHOWNORMAL)
+
+    def open_new(self, url):
+        self.open(url)
+
+
+DEFAULT_BROWSER = "command-line"
+
+if sys.platform[:3] == "win":
+    del _browsers["kfm"]
+    register("windows-default", WindowsDefault)
+    DEFAULT_BROWSER = "windows-default"
+elif os.environ.get("DISPLAY"):
+    if os.environ.get("KDEDIR"):
+        DEFAULT_BROWSER = "kfm"
+    elif _iscommand("netscape"):
+        DEFAULT_BROWSER = "netscape"
+
+# If the $BROWSER environment variable is set and true, let that be
+# the name of the browser to use:
+#
+DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
+
+
+# Now try to support the MacOS world.  This is the only supported
+# controller on that platform, so don't mess with the default!
+
+try:
+    import ic
+except ImportError:
+    pass
+else:
+    class InternetConfig:
+        def open(self, url, new=0):
+            ic.launcurl(url)
+
+        def open_new(self, url):
+            self.open(url)
+
+    _browsers.clear()
+    register("internet-config", InternetConfig)
+    DEFAULT_BROWSER = "internet-config"