diff --git a/Tools/webchecker/README b/Tools/webchecker/README
index ac723ea..9ef5b47 100644
--- a/Tools/webchecker/README
+++ b/Tools/webchecker/README
@@ -6,9 +6,15 @@
 validity.  The main program is "webchecker.py".  See its doc string
 (or invoke it with the option "-?") for more defails.
 
-The module robotparser.py was written by Skip Montanaro; the rest is
-original work.
+History:
 
-Jan 29, 1997.
+- Jan 1997.  First release.  The module robotparser.py was written by
+Skip Montanaro; the rest is original work by Guido van Rossum.
 
---Guido van Rossum (home page: http://www.python.org/~guido/)
+- May 1999.  Sam Bayer contributed a new version, wcnew.py, which
+supports checking internal links (#spam fragments in URLs) and some
+other options.
+
+- Nov 1999.  Sam Bayer contributed patches to reintegrate wcnew.py
+into webchecker.py, and corresponding mods to wcgui.py and
+websucker.py.
diff --git a/Tools/webchecker/wcnew.py b/Tools/webchecker/wcnew.py
deleted file mode 100755
index 2fa068d..0000000
--- a/Tools/webchecker/wcnew.py
+++ /dev/null
@@ -1,908 +0,0 @@
-#! /usr/bin/env python
-
-# Modifications where indicated by Samuel Bayer (SLB), 2/24/99,
-# to support checking of links to internal NAME anchors. Key 
-# modifications are in the dopage() method of the Checker class,
-# where the fragments (internal NAME anchors) associated with
-# a page are checked, and in the getlinkinfos() method of the
-# Page class, where the fragment element of the result of
-# urlparse() is saved, rather than discarded. The global effect
-# of this change is to make the entries in the "done" and 
-# "todo" instance variables of Checker into a pair (URL, fragment)
-# rather than simply a URL. This change has implications in 
-# the following methods:
-
-# addroot() of Checker
-# report_errors() of Checker
-# dopage() of Checker
-# newdonelink() of Checker
-# newtodolink() of Checker
-# format_url() of Checker (new)
-# getpage() of Checker
-# readhtml() of Checker
-# openhtml() of Checker
-# openpage() of Checker
-# seterror() of Checker
-# __init__() of Page()
-# getnames() of Page() (new)
-# getlinkinfos() of Page()
-# start_a() of MyHTMLParser()
-
-# Also added new command line argument to support specification of
-# additional roots, for the circumstance where a root the root index.html
-# page is not in a directory which dominates the entire tree of 
-# relevant internal references.
-
-"""Web tree checker.
-
-This utility is handy to check a subweb of the world-wide web for
-errors.  A subweb is specified by giving one or more ``root URLs''; a
-page belongs to the subweb if one of the root URLs is an initial
-prefix of it.
-
-File URL extension:
-
-In order to easy the checking of subwebs via the local file system,
-the interpretation of ``file:'' URLs is extended to mimic the behavior
-of your average HTTP daemon: if a directory pathname is given, the
-file index.html in that directory is returned if it exists, otherwise
-a directory listing is returned.  Now, you can point webchecker to the
-document tree in the local file system of your HTTP daemon, and have
-most of it checked.  In fact the default works this way if your local
-web tree is located at /usr/local/etc/httpd/htdpcs (the default for
-the NCSA HTTP daemon and probably others).
-
-Report printed:
-
-When done, it reports pages with bad links within the subweb.  When
-interrupted, it reports for the pages that it has checked already.
-
-In verbose mode, additional messages are printed during the
-information gathering phase.  By default, it prints a summary of its
-work status every 50 URLs (adjustable with the -r option), and it
-reports errors as they are encountered.  Use the -q option to disable
-this output.
-
-Checkpoint feature:
-
-Whether interrupted or not, it dumps its state (a Python pickle) to a
-checkpoint file and the -R option allows it to restart from the
-checkpoint (assuming that the pages on the subweb that were already
-processed haven't changed).  Even when it has run till completion, -R
-can still be useful -- it will print the reports again, and -Rq prints
-the errors only.  In this case, the checkpoint file is not written
-again.  The checkpoint file can be set with the -d option.
-
-The checkpoint file is written as a Python pickle.  Remember that
-Python's pickle module is currently quite slow.  Give it the time it
-needs to load and save the checkpoint file.  When interrupted while
-writing the checkpoint file, the old checkpoint file is not
-overwritten, but all work done in the current run is lost.
-
-Miscellaneous:
-
-- You may find the (Tk-based) GUI version easier to use.  See wcgui.py.
-
-- Webchecker honors the "robots.txt" convention.  Thanks to Skip
-Montanaro for his robotparser.py module (included in this directory)!
-The agent name is hardwired to "webchecker".  URLs that are disallowed
-by the robots.txt file are reported as external URLs.
-
-- Because the SGML parser is a bit slow, very large SGML files are
-skipped.  The size limit can be set with the -m option.
-
-- When the server or protocol does not tell us a file's type, we guess
-it based on the URL's suffix.  The mimetypes.py module (also in this
-directory) has a built-in table mapping most currently known suffixes,
-and in addition attempts to read the mime.types configuration files in
-the default locations of Netscape and the NCSA HTTP daemon.
-
-- We follow links indicated by <A>, <FRAME> and <IMG> tags.  We also
-honor the <BASE> tag.
-
-- (SLB 2/24/99) We now check internal NAME anchor links, as well
-as toplevel links.
-
-- Checking external links is now done by default; use -x to *disable*
-this feature.  External links are now checked during normal
-processing.  (XXX The status of a checked link could be categorized
-better.  Later...)
-
-- (SLB 2/24/99) If external links are not checked, you can use the -t
-flag to provide specific overrides to -x.
-
-Usage: webchecker.py [option] ... [rooturl] ...
-
-Options:
-
--R        -- restart from checkpoint file
--d file   -- checkpoint filename (default %(DUMPFILE)s)
--m bytes  -- skip HTML pages larger than this size (default %(MAXPAGE)d)
--n        -- reports only, no checking (use with -R)
--q        -- quiet operation (also suppresses external links report)
--r number -- number of links processed per round (default %(ROUNDSIZE)d)
--t root   -- specify root dir which should be treated as internal (can repeat)
--v        -- verbose operation; repeating -v will increase verbosity
--x        -- don't check external links (these are often slow to check)
--a        -- don't check name anchors
-
-Arguments:
-
-rooturl   -- URL to start checking
-             (default %(DEFROOT)s)
-
-"""
-
-
-__version__ = "$Revision$"
-
-
-import sys
-import os
-from types import *
-import string
-import StringIO
-import getopt
-import pickle
-
-import urllib
-import urlparse
-import sgmllib
-
-import mimetypes
-import robotparser
-
-# Extract real version number if necessary
-if __version__[0] == '$':
-    _v = string.split(__version__)
-    if len(_v) == 3:
-        __version__ = _v[1]
-
-
-# Tunable parameters
-DEFROOT = "file:/usr/local/etc/httpd/htdocs/"   # Default root URL
-CHECKEXT = 1                            # Check external references (1 deep)
-VERBOSE = 1                             # Verbosity level (0-3)
-MAXPAGE = 150000                        # Ignore files bigger than this
-ROUNDSIZE = 50                          # Number of links processed per round
-DUMPFILE = "@webchecker.pickle"         # Pickled checkpoint
-AGENTNAME = "webchecker"                # Agent name for robots.txt parser
-NONAMES = 0                             # Force name anchor checking
-
-
-# Global variables
-
-
-def main():
-    checkext = CHECKEXT
-    verbose = VERBOSE
-    maxpage = MAXPAGE
-    roundsize = ROUNDSIZE
-    dumpfile = DUMPFILE
-    restart = 0
-    norun = 0
-
-    try:
-
-        # Begin SLB 2/24/99: Added -t option here.
-        opts, args = getopt.getopt(sys.argv[1:], 'Rd:m:nqr:t:vxa')
-        # End SLB 2/24/99
-
-    except getopt.error, msg:
-        sys.stdout = sys.stderr
-        print msg
-        print __doc__%globals()
-        sys.exit(2)
-
-    # Begin SLB 2/24/99: Added extra_roots variable to
-    # collect extra roots.
-    extra_roots = []
-    nonames = NONAMES
-    # End SLB 2/24/99
-
-    for o, a in opts:
-        if o == '-R':
-            restart = 1
-        if o == '-d':
-            dumpfile = a
-        if o == '-m':
-            maxpage = string.atoi(a)
-        if o == '-n':
-            norun = 1
-        if o == '-q':
-            verbose = 0
-        if o == '-r':
-            roundsize = string.atoi(a)
-
-        # Begin SLB 2/24/99: Added processing for
-        # -t option.
-        if o == '-t':
-            extra_roots.append(a)
-        if o == '-a':
-            nonames = not nonames
-        # End SLB 2/24/99
-
-        if o == '-v':
-            verbose = verbose + 1
-        if o == '-x':
-            checkext = not checkext
-
-    if verbose > 0:
-        print AGENTNAME, "version", __version__
-
-    if restart:
-        c = load_pickle(dumpfile=dumpfile, verbose=verbose)
-    else:
-        c = Checker()
-
-    c.setflags(checkext=checkext, verbose=verbose,
-               maxpage=maxpage, roundsize=roundsize,
-               nonames=nonames
-               )
-
-    if not restart and not args:
-        args.append(DEFROOT)
-
-    for arg in args:
-        c.addroot(arg)
-
-    # Begin SLB 2/24/99. The -t flag is only needed if external
-    # links are not to be checked. So -t values are ignored unless
-    # -x was specified.
-    if not checkext:
-        for root in extra_roots:
-            # Make sure it's terminated by a slash,
-            # so that addroot doesn't discard the last
-            # directory component.
-            if root[-1] != "/":
-                root = root + "/"
-            c.addroot(root, add_to_do = 0)
-    # End SLB 2/24/99
-
-    try:
-
-        if not norun:
-            try:
-                c.run()
-            except KeyboardInterrupt:
-                if verbose > 0:
-                    print "[run interrupted]"
-
-        try:
-            c.report()
-        except KeyboardInterrupt:
-            if verbose > 0:
-                print "[report interrupted]"
-
-    finally:
-        if c.save_pickle(dumpfile):
-            if dumpfile == DUMPFILE:
-                print "Use ``%s -R'' to restart." % sys.argv[0]
-            else:
-                print "Use ``%s -R -d %s'' to restart." % (sys.argv[0],
-                                                           dumpfile)
-
-
-def load_pickle(dumpfile=DUMPFILE, verbose=VERBOSE):
-    if verbose > 0:
-        print "Loading checkpoint from %s ..." % dumpfile
-    f = open(dumpfile, "rb")
-    c = pickle.load(f)
-    f.close()
-    if verbose > 0:
-        print "Done."
-        print "Root:", string.join(c.roots, "\n      ")
-    return c
-
-
-class Checker:
-
-    checkext = CHECKEXT
-    verbose = VERBOSE
-    maxpage = MAXPAGE
-    roundsize = ROUNDSIZE
-    nonames = NONAMES
-
-    validflags = tuple(dir())
-
-    def __init__(self):
-        self.reset()
-
-    def setflags(self, **kw):
-        for key in kw.keys():
-            if key not in self.validflags:
-                raise NameError, "invalid keyword argument: %s" % str(key)
-        for key, value in kw.items():
-            setattr(self, key, value)
-
-    def reset(self):
-        self.roots = []
-        self.todo = {}
-        self.done = {}
-        self.bad = {}
-
-        # Begin SLB 2/24/99: Added a name table, so that the
-        # name URLs can be checked. Also serves as an implicit
-        # cache for which URLs are done.
-        self.name_table = {}
-        # End SLB 2/24/99
-
-        self.round = 0
-        # The following are not pickled:
-        self.robots = {}
-        self.errors = {}
-        self.urlopener = MyURLopener()
-        self.changed = 0
-
-    def note(self, level, format, *args):
-        if self.verbose > level:
-            if args:
-                format = format%args
-            self.message(format)
-
-    def message(self, format, *args):
-        if args:
-            format = format%args
-        print format 
-
-    def __getstate__(self):
-        return (self.roots, self.todo, self.done, self.bad, self.round)
-
-    def __setstate__(self, state):
-        self.reset()
-        (self.roots, self.todo, self.done, self.bad, self.round) = state
-        for root in self.roots:
-            self.addrobot(root)
-        for url in self.bad.keys():
-            self.markerror(url)
-
-    def addroot(self, root, add_to_do = 1):
-        if root not in self.roots:
-            troot = root
-            scheme, netloc, path, params, query, fragment = \
-                    urlparse.urlparse(root)
-            i = string.rfind(path, "/") + 1
-            if 0 < i < len(path):
-                path = path[:i]
-                troot = urlparse.urlunparse((scheme, netloc, path,
-                                             params, query, fragment))
-            self.roots.append(troot)
-            self.addrobot(root)
-            # Begin SLB 2/24/99: Modified this call to respect
-            # the fact that the "done" and "todo" dictionaries
-            # are now (URL, fragment) pairs
-            if add_to_do:
-                self.newlink((root, ""), ("<root>", root))
-            # End SLB 2/24/99
-
-    def addrobot(self, root):
-        root = urlparse.urljoin(root, "/")
-        if self.robots.has_key(root): return
-        url = urlparse.urljoin(root, "/robots.txt")
-        self.robots[root] = rp = robotparser.RobotFileParser()
-        self.note(2, "Parsing %s", url)
-        rp.debug = self.verbose > 3
-        rp.set_url(url)
-        try:
-            rp.read()
-        except IOError, msg:
-            self.note(1, "I/O error parsing %s: %s", url, msg)
-
-    def run(self):
-        while self.todo:
-            self.round = self.round + 1
-            self.note(0, "\nRound %d (%s)\n", self.round, self.status())
-            urls = self.todo.keys()
-            urls.sort()
-            del urls[self.roundsize:]
-            for url in urls:
-                self.dopage(url)
-
-    def status(self):
-        return "%d total, %d to do, %d done, %d bad" % (
-            len(self.todo)+len(self.done),
-            len(self.todo), len(self.done),
-            len(self.bad))
-
-    def report(self):
-        self.message("")
-        if not self.todo: s = "Final"
-        else: s = "Interim"
-        self.message("%s Report (%s)", s, self.status())
-        self.report_errors()
-
-    def report_errors(self):
-        if not self.bad:
-            self.message("\nNo errors")
-            return
-        self.message("\nError Report:")
-        sources = self.errors.keys()
-        sources.sort()
-        for source in sources:
-            triples = self.errors[source]
-            self.message("")
-            if len(triples) > 1:
-                self.message("%d Errors in %s", len(triples), source)
-            else:
-                self.message("Error in %s", source)
-            # Begin SLB 2/24/99: Modified this loop to
-            # call self.format_url() instead of referring
-            # to the URL directly, since the URLs in these
-            # triples is now a (URL, fragment) pair. The value
-            # of the "source" variable comes from the list of
-            # origins, and is a URL, not a pair.
-            for url, rawlink, msg in triples:           
-                if rawlink != self.format_url(url): s = " (%s)" % rawlink
-                else: s = ""
-                self.message("  HREF %s%s\n    msg %s",
-                             self.format_url(url), s, msg)
-            # End SLB 2/24/99.
-
-    def dopage(self, url_pair):
-
-        # Begin SLB 2/24/99: Substantial modification to reflect the change
-        # to dictionary entries being (URL, fragment) pairs. All
-        # printing of URLs uses format_url(); argument changed to
-        # url_pair for clarity.
-        if self.verbose > 1:
-            if self.verbose > 2:
-                self.show("Check ", self.format_url(url_pair),
-                          "  from", self.todo[url_pair])
-            else:
-                self.message("Check %s", self.format_url(url_pair))
-        url, local_fragment = url_pair
-        if local_fragment and self.nonames:
-            self.markdone(url_pair)
-            return
-        page = self.getpage(url_pair)
-        if page:
-            # Store the page which corresponds to this URL.
-            self.name_table[url] = page
-            # If there is a fragment in this url_pair, and it's not
-            # in the list of names for the page, call setbad(), since
-            # it's a missing anchor.
-            if local_fragment and local_fragment not in page.getnames():
-                self.setbad(url_pair, ("Missing name anchor `%s'" % local_fragment))
-            for info in page.getlinkinfos():
-                # getlinkinfos() now returns the fragment as well,
-                # and we store that fragment here in the "todo" dictionary.
-                link, rawlink, fragment = info
-                # However, we don't want the fragment as the origin, since
-                # the origin is logically a page.
-                origin = url, rawlink
-                self.newlink((link, fragment), origin)
-        else:
-            # If no page has been created yet, we want to
-            # record that fact.
-            self.name_table[url_pair[0]] = None
-        self.markdone(url_pair)
-        # End SLB 2/24/99
-
-    def newlink(self, url, origin):
-        if self.done.has_key(url):
-            self.newdonelink(url, origin)
-        else:
-            self.newtodolink(url, origin)
-
-    def newdonelink(self, url, origin):
-
-        if origin not in self.done[url]:
-            self.done[url].append(origin)
-
-        # Begin SLB 2/24/99: changed reference to URL
-        # to call self.format_url(), since the URL here
-        # is now a (URL, fragment) pair.
-        self.note(3, "  Done link %s", self.format_url(url))
-
-        # SLB 11/11/99: Make sure that if it's bad, that
-        # the origin gets added.
-
-        if self.bad.has_key(url):
-            source, rawlink = origin
-            triple = url, rawlink, self.bad[url]
-            self.seterror(source, triple)
-
-        # End SLB 2/24/99
-
-    def newtodolink(self, url, origin):
-
-        # Begin SLB 2/24/99: changed reference to URL
-        # to call self.format_url(), since the URL here
-        # is now a (URL, fragment) pair.
-        if self.todo.has_key(url):
-            if origin not in self.todo[url]:
-                self.todo[url].append(origin)
-            self.note(3, "  Seen todo link %s", self.format_url(url))
-        else:
-            self.todo[url] = [origin]
-            self.note(3, "  New todo link %s", self.format_url(url))
-        # End SLB 2/24/99
-
-    # Begin SLB 2/24/99: Added method format_url().
-    def format_url(self, url):  
-        link, fragment = url
-        if fragment: return link + "#" + fragment
-        else: return link
-    # End SLB 2/24/99
-
-    def markdone(self, url):
-        self.done[url] = self.todo[url]
-        del self.todo[url]
-        self.changed = 1
-
-    def inroots(self, url):
-        for root in self.roots:
-            if url[:len(root)] == root:
-                return self.isallowed(root, url)
-        return 0
-
-    def isallowed(self, root, url):
-        root = urlparse.urljoin(root, "/")
-        return self.robots[root].can_fetch(AGENTNAME, url)
-
-    def getpage(self, url_pair):
-
-        # Begin SLB 2/24/99: changed incoming argument name to 
-        # url_pair, since it's now a (URL, fragment) pair.
-        # The page may have been cached in the name_table variable.
-        url, fragment = url_pair
-        if self.name_table.has_key(url):
-            return self.name_table[url]
-        # End SLB 2/24/99
-
-        if url[:7] == 'mailto:' or url[:5] == 'news:':
-            self.note(1, " Not checking mailto/news URL")
-            return None
-        isint = self.inroots(url)
-
-        # Begin SLB 2/24/99: Changed calls to openpage and readhtml
-        # in order to ensure that openpage gets the URL pair to
-        # print out its error message and record the error pair
-        # correctly.
-        if not isint:
-            if not self.checkext:
-                self.note(1, " Not checking ext link")
-                return None
-            f = self.openpage(url_pair)
-            if f:
-                self.safeclose(f)
-            return None
-        text, nurl = self.readhtml(url_pair)
-        # End SLB 2/24/99
-
-        if nurl != url:
-            self.note(1, " Redirected to %s", nurl)
-            url = nurl
-        if text:
-            return Page(text, url, maxpage=self.maxpage, checker=self)
-
-    # Begin SLB 2/24/99: Modified these next three functions
-    # to take (URL, fragment) pairs as arguments, so that openpage()
-    # receives the appropriate tuple to record error messages.
-    def readhtml(self, url_pair):
-        url, fragment = url_pair
-        text = None
-        f, url = self.openhtml(url_pair)
-        if f:
-            text = f.read()
-            f.close()
-        return text, url
-
-    def openhtml(self, url_pair):
-        url, fragment = url_pair
-        f = self.openpage(url_pair)
-        if f:
-            url = f.geturl()
-            info = f.info()
-            if not self.checkforhtml(info, url):
-                self.safeclose(f)
-                f = None
-        return f, url
-
-    def openpage(self, url_pair):
-        url, fragment = url_pair
-        try:
-            return self.urlopener.open(url)
-        except IOError, msg:
-            msg = self.sanitize(msg)
-            self.note(0, "Error %s", msg)
-            if self.verbose > 0:
-                self.show(" HREF ", url, "  from", self.todo[url_pair])
-            self.setbad(url_pair, msg)
-            return None
-    # End SLB 2/24/99
-
-    def checkforhtml(self, info, url):
-        if info.has_key('content-type'):
-            ctype = string.lower(info['content-type'])
-        else:
-            if url[-1:] == "/":
-                return 1
-            ctype, encoding = mimetypes.guess_type(url)
-        if ctype == 'text/html':
-            return 1
-        else:
-            self.note(1, " Not HTML, mime type %s", ctype)
-            return 0
-
-    def setgood(self, url):
-        if self.bad.has_key(url):
-            del self.bad[url]
-            self.changed = 1
-            self.note(0, "(Clear previously seen error)")
-
-    def setbad(self, url, msg):
-        if self.bad.has_key(url) and self.bad[url] == msg:
-            self.note(0, "(Seen this error before)")
-            return
-        self.bad[url] = msg
-        self.changed = 1
-        self.markerror(url)
-
-    def markerror(self, url):
-        try:
-            origins = self.todo[url]
-        except KeyError:
-            origins = self.done[url]
-        for source, rawlink in origins:
-            triple = url, rawlink, self.bad[url]
-            self.seterror(source, triple)
-
-    def seterror(self, url, triple):
-        try:
-
-            # Begin SLB 2/24/99: Because of the way the
-            # URLs are now processed, I need to check to make
-            # sure the URL hasn't been entered in the error list.
-            # The first element of the triple here is a (URL, fragment)
-            # pair, but the URL key is not, since it's from the
-            # list of origins.
-            if triple not in self.errors[url]:
-                self.errors[url].append(triple)
-            # End SLB 2/24/99
-
-        except KeyError:
-            self.errors[url] = [triple]
-
-    # The following used to be toplevel functions; they have been
-    # changed into methods so they can be overridden in subclasses.
-
-    def show(self, p1, link, p2, origins):
-        self.message("%s %s", p1, link)
-        i = 0
-        for source, rawlink in origins:
-            i = i+1
-            if i == 2:
-                p2 = ' '*len(p2)
-            if rawlink != link: s = " (%s)" % rawlink
-            else: s = ""
-            self.message("%s %s%s", p2, source, s)
-
-    def sanitize(self, msg):
-        if isinstance(IOError, ClassType) and isinstance(msg, IOError):
-            # Do the other branch recursively
-            msg.args = self.sanitize(msg.args)
-        elif isinstance(msg, TupleType):
-            if len(msg) >= 4 and msg[0] == 'http error' and \
-               isinstance(msg[3], InstanceType):
-                # Remove the Message instance -- it may contain
-                # a file object which prevents pickling.
-                msg = msg[:3] + msg[4:]
-        return msg
-
-    def safeclose(self, f):
-        try:
-            url = f.geturl()
-        except AttributeError:
-            pass
-        else:
-            if url[:4] == 'ftp:' or url[:7] == 'file://':
-                # Apparently ftp connections don't like to be closed
-                # prematurely...
-                text = f.read()
-        f.close()
-
-    def save_pickle(self, dumpfile=DUMPFILE):
-        if not self.changed:
-            self.note(0, "\nNo need to save checkpoint")
-        elif not dumpfile:
-            self.note(0, "No dumpfile, won't save checkpoint")
-        else:
-            self.note(0, "\nSaving checkpoint to %s ...", dumpfile)
-            newfile = dumpfile + ".new"
-            f = open(newfile, "wb")
-            pickle.dump(self, f)
-            f.close()
-            try:
-                os.unlink(dumpfile)
-            except os.error:
-                pass
-            os.rename(newfile, dumpfile)
-            self.note(0, "Done.")
-            return 1
-
-
-class Page:
-
-    def __init__(self, text, url, verbose=VERBOSE, maxpage=MAXPAGE, checker=None):
-        self.text = text
-        self.url = url
-        self.verbose = verbose
-        self.maxpage = maxpage
-        self.checker = checker
-
-        # Begin SLB 2/24/99: Moved the parsing of the page into
-        # the __init__() routine in order to initialize the list of
-        # names the file contains. Stored the parser in an instance
-        # variable. Passed the URL to MyHTMLParser().
-        size = len(self.text)
-        if size > self.maxpage:
-            self.note(0, "Skip huge file %s (%.0f Kbytes)", self.url, (size*0.001))
-            self.parser = None
-            return
-        self.checker.note(2, "  Parsing %s (%d bytes)", self.url, size)
-        self.parser = MyHTMLParser(url, verbose=self.verbose,
-                                   checker=self.checker)
-        self.parser.feed(self.text)
-        self.parser.close()
-        # End SLB 2/24/99
-
-    def note(self, level, msg, *args):
-        if self.checker:
-            apply(self.checker.note, (level, msg) + args)
-        else:
-            if self.verbose >= level:
-                if args:
-                    msg = msg%args
-                print msg
-
-    # Begin SLB 2/24/99: Added method to retrieve names.
-    def getnames(self):
-        return self.parser.names
-    # End SLB 2/24/99
-
-    def getlinkinfos(self):
-
-        # Begin SLB 2/24/99: Moved file reading to __init__() routine.
-        # Stored parser in local variable to indicate success of
-        # parsing.
-
-        # If no parser was stored, fail.
-        if not self.parser: return []
-
-        rawlinks = self.parser.getlinks()
-        base = urlparse.urljoin(self.url, self.parser.getbase() or "")
-        infos = []
-        for rawlink in rawlinks:
-            t = urlparse.urlparse(rawlink)
-            # DON'T DISCARD THE FRAGMENT! Instead, include
-            # it in the tuples which are returned. See Checker.dopage().
-            fragment = t[-1]
-            t = t[:-1] + ('',)
-            rawlink = urlparse.urlunparse(t)
-            link = urlparse.urljoin(base, rawlink)
-            infos.append((link, rawlink, fragment))     
-        # End SLB 2/24/99
-
-        return infos
-
-
-class MyStringIO(StringIO.StringIO):
-
-    def __init__(self, url, info):
-        self.__url = url
-        self.__info = info
-        StringIO.StringIO.__init__(self)
-
-    def info(self):
-        return self.__info
-
-    def geturl(self):
-        return self.__url
-
-
-class MyURLopener(urllib.FancyURLopener):
-
-    http_error_default = urllib.URLopener.http_error_default
-
-    def __init__(*args):
-        self = args[0]
-        apply(urllib.FancyURLopener.__init__, args)
-        self.addheaders = [
-            ('User-agent', 'Python-webchecker/%s' % __version__),
-            ]
-
-    def http_error_401(self, url, fp, errcode, errmsg, headers):
-        return None
-
-    def open_file(self, url):
-        path = urllib.url2pathname(urllib.unquote(url))
-        if os.path.isdir(path):
-            if path[-1] != os.sep:
-                url = url + '/'
-            indexpath = os.path.join(path, "index.html")
-            if os.path.exists(indexpath):
-                return self.open_file(url + "index.html")
-            try:
-                names = os.listdir(path)
-            except os.error, msg:
-                raise IOError, msg, sys.exc_traceback
-            names.sort()
-            s = MyStringIO("file:"+url, {'content-type': 'text/html'})
-            s.write('<BASE HREF="file:%s">\n' %
-                    urllib.quote(os.path.join(path, "")))
-            for name in names:
-                q = urllib.quote(name)
-                s.write('<A HREF="%s">%s</A>\n' % (q, q))
-            s.seek(0)
-            return s
-        return urllib.FancyURLopener.open_file(self, url)
-
-
-class MyHTMLParser(sgmllib.SGMLParser):
-
-    def __init__(self, url, verbose=VERBOSE, checker=None):
-        self.myverbose = verbose # now unused
-        self.checker = checker
-        self.base = None
-        self.links = {}
-
-        # Begin SLB 2/24/99: Added names instance variable.
-        # Modified arglist to take the URL as an argument.
-        self.names = []
-        self.url = url
-        # End SLB 2/24/99
-
-        sgmllib.SGMLParser.__init__(self)
-
-    def start_a(self, attributes):
-        self.link_attr(attributes, 'href')
-
-        # Begin SLB 2/24/99: We must rescue the NAME
-        # attributes from the anchor, in order to
-        # cache the internal anchors which are made
-        # available in the page.
-        for name, value in attributes:
-            if name == "name":
-                if value in self.names:
-                    self.checker.message("WARNING: duplicate name %s in %s",
-                                         value, self.url)
-                else: self.names.append(value)
-                break
-        # End SLB 2/24/99
-
-    def end_a(self): pass
-
-    def do_area(self, attributes):
-        self.link_attr(attributes, 'href')
-
-    def do_img(self, attributes):
-        self.link_attr(attributes, 'src', 'lowsrc')
-
-    def do_frame(self, attributes):
-        self.link_attr(attributes, 'src')
-
-    def link_attr(self, attributes, *args):
-        for name, value in attributes:
-            if name in args:
-                if value: value = string.strip(value)
-                if value: self.links[value] = None
-
-    def do_base(self, attributes):
-        for name, value in attributes:
-            if name == 'href':
-                if value: value = string.strip(value)
-                if value:
-                    if self.checker:
-                        self.checker.note(1, "  Base %s", value)
-                    self.base = value
-
-    def getlinks(self):
-        return self.links.keys()
-
-    def getbase(self):
-        return self.base
-
-
-if __name__ == '__main__':
-    main()
