diff --git a/Lib/cgitb.py b/Lib/cgitb.py
index 8084464..e9b0376 100644
--- a/Lib/cgitb.py
+++ b/Lib/cgitb.py
@@ -8,8 +8,9 @@
 
     display     - if true, tracebacks are displayed in the web browser
     logdir      - if set, tracebacks are written to files in this directory
+    context     - number of lines of source code to show for each stack frame
 
-By default, tracebacks are displayed but not written to files.
+By default, tracebacks are displayed but not saved, and context is 5.
 
 Alternatively, if you have caught an exception and want cgitb to display it
 for you, call cgitb.handle().  The optional argument to handle() is a 3-item
@@ -23,160 +24,177 @@
     return '''<!--: spam
 Content-Type: text/html
 
-<body bgcolor="#f0f0ff"><font color="#f0f0ff" size="-5"> -->
-<body bgcolor="#f0f0ff"><font color="#f0f0ff" size="-5"> --> -->
+<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->
+<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->
 </font> </font> </font> </script> </object> </blockquote> </pre>
 </table> </table> </table> </table> </table> </font> </font> </font>'''
 
-def html(etype, evalue, etb, context=5):
-    """Return a nice HTML document describing the traceback."""
-    import sys, os, types, time, traceback
-    import keyword, tokenize, linecache, inspect, pydoc
+__UNDEF__ = []                          # a special sentinel object
+def small(text): return '<small>' + text + '</small>'
+def strong(text): return '<strong>' + text + '</strong>'
+def grey(text): return '<font color="#909090">' + text + '</font>'
+
+def lookup(name, frame, locals):
+    """Find the value for a given name in the given environment."""
+    if name in locals:
+        return 'local', locals[name]
+    if name in frame.f_globals:
+        return 'global', frame.f_globals[name]
+    return None, __UNDEF__
+
+def scanvars(reader, frame, locals):
+    """Scan one logical line of Python and look up values of variables used."""
+    import tokenize, keyword
+    vars, lasttoken, parent, prefix = [], None, None, ''
+    for ttype, token, start, end, line in tokenize.generate_tokens(reader):
+        if ttype == tokenize.NEWLINE: break
+        if ttype == tokenize.NAME and token not in keyword.kwlist:
+            if lasttoken == '.':
+                if parent is not __UNDEF__:
+                    value = getattr(parent, token, __UNDEF__)
+                    vars.append((prefix + token, prefix, value))
+            else:
+                where, value = lookup(token, frame, locals)
+                vars.append((token, where, value))
+        elif token == '.':
+            prefix += lasttoken + '.'
+            parent = value
+        else:
+            parent, prefix = None, ''
+        lasttoken = token
+    return vars
+
+def html((etype, evalue, etb), context=5):
+    """Return a nice HTML document describing a given traceback."""
+    import sys, os, types, time, traceback, linecache, inspect, pydoc
 
     if type(etype) is types.ClassType:
         etype = etype.__name__
     pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
     date = time.ctime(time.time())
-    head = '<body bgcolor="#f0f0ff">' + pydoc.html.heading(
+    head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading(
         '<big><big><strong>%s</strong></big></big>' % str(etype),
-        '#ffffff', '#aa55cc', pyver + '<br>' + date) + '''
-<p>A problem occurred in a Python script.
-Here is the sequence of function calls leading up to
-the error, with the most recent (innermost) call last.'''
+        '#ffffff', '#6622aa', pyver + '<br>' + date) + '''
+<p>A problem occurred in a Python script.  Here is the sequence of
+function calls leading up to the error, in the order they occurred.'''
 
-    indent = '<tt><small>' + '&nbsp;' * 5 + '</small>&nbsp;</tt>'
+    indent = '<tt>' + small('&nbsp;' * 5) + '&nbsp;</tt>'
     frames = []
     records = inspect.getinnerframes(etb, context)
     for frame, file, lnum, func, lines, index in records:
         file = file and os.path.abspath(file) or '?'
-        link = '<a href="file:%s">%s</a>' % (file, pydoc.html.escape(file))
+        link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file))
         args, varargs, varkw, locals = inspect.getargvalues(frame)
-        if func == '?':
-            call = ''
-        else:
-            def eqrepr(value): return '=' + pydoc.html.repr(value)
-            call = 'in <strong>%s</strong>' % func + inspect.formatargvalues(
-                    args, varargs, varkw, locals, formatvalue=eqrepr)
+        call = ''
+        if func != '?':
+            call = 'in ' + strong(func) + \
+                inspect.formatargvalues(args, varargs, varkw, locals,
+                    formatvalue=lambda value: '=' + pydoc.html.repr(value))
 
-        names = []
-        def tokeneater(type, token, start, end, line):
-            if type == tokenize.NAME and token not in keyword.kwlist:
-                if token not in names: names.append(token)
-            if type == tokenize.NEWLINE: raise IndexError
-        def linereader(lnum=[lnum]):
-            line = linecache.getline(file, lnum[0])
-            lnum[0] += 1
-            return line
+        highlight = {}
+        def reader(lnum=[lnum]):
+            highlight[lnum[0]] = 1
+            try: return linecache.getline(file, lnum[0])
+            finally: lnum[0] += 1
+        vars = scanvars(reader, frame, locals)
 
-        try:
-            tokenize.tokenize(linereader, tokeneater)
-        except IndexError: pass
-        lvals = []
-        for name in names:
-            if name in frame.f_code.co_varnames:
-                if locals.has_key(name):
-                    value = pydoc.html.repr(locals[name])
-                else:
-                    value = '<em>undefined</em>'
-                name = '<strong>%s</strong>' % name
-            else:
-                if frame.f_globals.has_key(name):
-                    value = pydoc.html.repr(frame.f_globals[name])
-                else:
-                    value = '<em>undefined</em>'
-                name = '<em>global</em> <strong>%s</strong>' % name
-            lvals.append('%s&nbsp;= %s' % (name, value))
-        if lvals:
-            lvals = indent + '''
-<small><font color="#909090">%s</font></small><br>''' % (', '.join(lvals))
-        else:
-            lvals = ''
-
-        level = '''
-<table width="100%%" bgcolor="#d8bbff" cellspacing=0 cellpadding=2 border=0>
-<tr><td>%s %s</td></tr></table>\n''' % (link, call)
-        excerpt = []
+        rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' %
+                ('<big>&nbsp;</big>', link, call)]
         if index is not None:
             i = lnum - index
             for line in lines:
-                num = '<small><font color="#909090">%s</font></small>' % (
-                    '&nbsp;' * (5-len(str(i))) + str(i))
-                line = '<tt>%s&nbsp;%s</tt>' % (num, pydoc.html.preformat(line))
-                if i == lnum:
-                    line = '''
-<table width="100%%" bgcolor="#ffccee" cellspacing=0 cellpadding=0 border=0>
-<tr><td>%s</td></tr></table>\n''' % line
-                excerpt.append('\n' + line)
-                if i == lnum:
-                    excerpt.append(lvals)
-                i = i + 1
-        frames.append('<p>' + level + '\n'.join(excerpt))
+                num = small('&nbsp;' * (5-len(str(i))) + str(i)) + '&nbsp;'
+                line = '<tt>%s%s</tt>' % (num, pydoc.html.preformat(line))
+                if i in highlight:
+                    rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)
+                else:
+                    rows.append('<tr><td>%s</td></tr>' % grey(line))
+                i += 1
 
-    exception = ['<p><strong>%s</strong>: %s' % (str(etype), str(evalue))]
+        done, dump = {}, []
+        for name, where, value in vars:
+            if name in done: continue
+            done[name] = 1
+            if value is not __UNDEF__:
+                if where == 'global': name = '<em>global</em> ' + strong(name)
+                elif where == 'local': name = strong(name)
+                else: name = where + strong(name.split('.')[-1])
+                dump.append('%s&nbsp;= %s' % (name, pydoc.html.repr(value)))
+            else:
+                dump.append(name + ' <em>undefined</em>')
+
+        rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump))))
+        frames.append('''<p>
+<table width="100%%" cellspacing=0 cellpadding=0 border=0>
+%s</table>''' % '\n'.join(rows))
+
+    exception = ['<p>%s: %s' % (strong(str(etype)), str(evalue))]
     if type(evalue) is types.InstanceType:
         for name in dir(evalue):
             value = pydoc.html.repr(getattr(evalue, name))
             exception.append('\n<br>%s%s&nbsp;=\n%s' % (indent, name, value))
 
     import traceback
-    plaintrace = ''.join(traceback.format_exception(etype, evalue, etb))
-
     return head + ''.join(frames) + ''.join(exception) + '''
 
 
-<!-- The above is a description of an error that occurred in a Python program.
-     It is formatted for display in a Web browser because it appears that
-     we are running in a CGI environment.  In case you are viewing this
-     message outside of a Web browser, here is the original error traceback:
+<!-- The above is a description of an error in a Python program, formatted
+     for a Web browser because the 'cgitb' module was enabled.  In case you
+     are not reading this in a Web browser, here is the original traceback:
 
 %s
 -->
-''' % plaintrace
+''' % ''.join(traceback.format_exception(etype, evalue, etb))
 
 class Hook:
-    def __init__(self, display=1, logdir=None):
+    """A hook to replace sys.excepthook that shows tracebacks in HTML."""
+
+    def __init__(self, display=1, logdir=None, context=5):
         self.display = display          # send tracebacks to browser if true
         self.logdir = logdir            # log tracebacks to files if not None
+        self.context = context          # number of source code lines per frame
 
     def __call__(self, etype, evalue, etb):
-        """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
         self.handle((etype, evalue, etb))
 
     def handle(self, info=None):
-        import sys, os
+        import sys
         info = info or sys.exc_info()
-        text = 0
         print reset()
 
         try:
-            doc = html(*info)
+            text, doc = 0, html(info, self.context)
         except:                         # just in case something goes wrong
             import traceback
-            doc = ''.join(traceback.format_exception(*info))
-            text = 1
+            text, doc = 1, ''.join(traceback.format_exception(*info))
 
         if self.display:
             if text:
                 doc = doc.replace('&', '&amp;').replace('<', '&lt;')
-                print '<pre>', doc, '</pre>'
+                print '<pre>' + doc + '</pre>'
             else:
                 print doc
         else:
             print '<p>A problem occurred in a Python script.'
 
         if self.logdir is not None:
-            import tempfile
+            import os, tempfile
             name = tempfile.mktemp(['.html', '.txt'][text])
             path = os.path.join(self.logdir, os.path.basename(name))
             try:
                 file = open(path, 'w')
                 file.write(doc)
                 file.close()
-                print '<p>%s contains the description of this error.' % path
+                print '<p> %s contains the description of this error.' % path
             except:
-                print '<p>Tried to write to %s, but failed.' % path
+                print '<p> Tried to save traceback to %s, but failed.' % path
 
 handler = Hook().handle
-def enable(display=1, logdir=None):
+def enable(display=1, logdir=None, context=5):
+    """Install an exception handler that formats tracebacks as HTML.
+
+    The optional argument 'display' can be set to 0 to suppress sending the
+    traceback to the browser, and 'logdir' can be set to a directory to cause
+    tracebacks to be written to files there."""
     import sys
-    sys.excepthook = Hook(display, logdir)
+    sys.excepthook = Hook(display, logdir, context)
