diff --git a/Tools/webchecker/tktools.py b/Tools/webchecker/tktools.py
new file mode 100644
index 0000000..6734530
--- /dev/null
+++ b/Tools/webchecker/tktools.py
@@ -0,0 +1,367 @@
+"""Assorted Tk-related subroutines used in Grail."""
+
+
+import string
+from types import *
+from Tkinter import *
+
+def _clear_entry_widget(event):
+    try:
+	widget = event.widget
+	widget.delete(0, INSERT)
+    except: pass
+def install_keybindings(root):
+    root.bind_class('Entry', '<Control-u>', _clear_entry_widget)
+
+
+def make_toplevel(master, title=None, class_=None):
+    """Create a Toplevel widget.
+
+    This is a shortcut for a Toplevel() instantiation plus calls to
+    set the title and icon name of the widget.
+
+    """
+
+    if class_:
+	widget = Toplevel(master, class_=class_)
+    else:
+	widget = Toplevel(master)
+    if title:
+	widget.title(title)
+	widget.iconname(title)
+    return widget
+
+def set_transient(widget, master, relx=0.5, rely=0.3, expose=1):
+    """Make an existing toplevel widget transient for a master.
+
+    The widget must exist but should not yet have been placed; in
+    other words, this should be called after creating all the
+    subwidget but before letting the user interact.
+    """
+
+    widget.withdraw() # Remain invisible while we figure out the geometry
+    widget.transient(master)
+    widget.update_idletasks() # Actualize geometry information
+    if master.winfo_ismapped():
+	m_width = master.winfo_width()
+	m_height = master.winfo_height()
+	m_x = master.winfo_rootx()
+	m_y = master.winfo_rooty()
+    else:
+	m_width = master.winfo_screenwidth()
+	m_height = master.winfo_screenheight()
+	m_x = m_y = 0
+    w_width = widget.winfo_reqwidth()
+    w_height = widget.winfo_reqheight()
+    x = m_x + (m_width - w_width) * relx
+    y = m_y + (m_height - w_height) * rely
+    widget.geometry("+%d+%d" % (x, y))
+    if expose:
+	widget.deiconify()	# Become visible at the desired location
+    return widget
+
+
+def make_scrollbars(parent, hbar, vbar, pack=1, class_=None, name=None,
+		    takefocus=0):
+
+    """Subroutine to create a frame with scrollbars.
+
+    This is used by make_text_box and similar routines.
+
+    Note: the caller is responsible for setting the x/y scroll command
+    properties (e.g. by calling set_scroll_commands()).
+
+    Return a tuple containing the hbar, the vbar, and the frame, where
+    hbar and vbar are None if not requested.
+
+    """
+    if class_:
+	if name: frame = Frame(parent, class_=class_, name=name)
+	else: frame = Frame(parent, class_=class_)
+    else:
+	if name: frame = Frame(parent, name=name)
+	else: frame = Frame(parent)
+
+    if pack:
+	frame.pack(fill=BOTH, expand=1)
+
+    corner = None
+    if vbar:
+	if not hbar:
+	    vbar = Scrollbar(frame, takefocus=takefocus)
+	    vbar.pack(fill=Y, side=RIGHT)
+	else:
+	    vbarframe = Frame(frame, borderwidth=0)
+	    vbarframe.pack(fill=Y, side=RIGHT)
+	    vbar = Scrollbar(frame, name="vbar", takefocus=takefocus)
+	    vbar.pack(in_=vbarframe, expand=1, fill=Y, side=TOP)
+	    sbwidth = vbar.winfo_reqwidth()
+	    corner = Frame(vbarframe, width=sbwidth, height=sbwidth)
+	    corner.propagate(0)
+	    corner.pack(side=BOTTOM)
+    else:
+	vbar = None
+
+    if hbar:
+	hbar = Scrollbar(frame, orient=HORIZONTAL, name="hbar",
+			 takefocus=takefocus)
+	hbar.pack(fill=X, side=BOTTOM)
+    else:
+	hbar = None
+
+    return hbar, vbar, frame
+
+
+def set_scroll_commands(widget, hbar, vbar):
+
+    """Link a scrollable widget to its scroll bars.
+
+    The scroll bars may be empty.
+
+    """
+
+    if vbar:
+	widget['yscrollcommand'] = (vbar, 'set')
+	vbar['command'] = (widget, 'yview')
+
+    if hbar:
+	widget['xscrollcommand'] = (hbar, 'set')
+	hbar['command'] = (widget, 'xview')
+
+    widget.vbar = vbar
+    widget.hbar = hbar
+
+
+def make_text_box(parent, width=0, height=0, hbar=0, vbar=1,
+		  fill=BOTH, expand=1, wrap=WORD, pack=1,
+		  class_=None, name=None, takefocus=None):
+
+    """Subroutine to create a text box.
+
+    Create:
+    - a both-ways filling and expanding frame, containing:
+      - a text widget on the left, and
+      - possibly a vertical scroll bar on the right.
+      - possibly a horizonta; scroll bar at the bottom.
+
+    Return the text widget and the frame widget.
+
+    """
+    hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
+					class_=class_, name=name,
+					takefocus=takefocus)
+
+    widget = Text(frame, wrap=wrap, name="text")
+    if width: widget.config(width=width)
+    if height: widget.config(height=height)
+    widget.pack(expand=expand, fill=fill, side=LEFT)
+
+    set_scroll_commands(widget, hbar, vbar)
+
+    return widget, frame
+
+
+def make_list_box(parent, width=0, height=0, hbar=0, vbar=1,
+		  fill=BOTH, expand=1, pack=1, class_=None, name=None,
+		  takefocus=None):
+
+    """Subroutine to create a list box.
+
+    Like make_text_box().
+    """
+    hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
+					class_=class_, name=name,
+					takefocus=takefocus)
+
+    widget = Listbox(frame, name="listbox")
+    if width: widget.config(width=width)
+    if height: widget.config(height=height)
+    widget.pack(expand=expand, fill=fill, side=LEFT)
+
+    set_scroll_commands(widget, hbar, vbar)
+
+    return widget, frame
+
+
+def make_canvas(parent, width=0, height=0, hbar=1, vbar=1,
+		fill=BOTH, expand=1, pack=1, class_=None, name=None,
+		takefocus=None):
+
+    """Subroutine to create a canvas.
+
+    Like make_text_box().
+
+    """
+
+    hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
+					class_=class_, name=name,
+					takefocus=takefocus)
+
+    widget = Canvas(frame, scrollregion=(0, 0, width, height), name="canvas")
+    if width: widget.config(width=width)
+    if height: widget.config(height=height)
+    widget.pack(expand=expand, fill=fill, side=LEFT)
+
+    set_scroll_commands(widget, hbar, vbar)
+
+    return widget, frame
+
+
+
+def make_form_entry(parent, label, borderwidth=None):
+
+    """Subroutine to create a form entry.
+
+    Create:
+    - a horizontally filling and expanding frame, containing:
+      - a label on the left, and
+      - a text entry on the right.
+
+    Return the entry widget and the frame widget.
+
+    """
+
+    frame = Frame(parent)
+    frame.pack(fill=X)
+
+    label = Label(frame, text=label)
+    label.pack(side=LEFT)
+
+    if borderwidth is None:
+	entry = Entry(frame, relief=SUNKEN)
+    else:
+	entry = Entry(frame, relief=SUNKEN, borderwidth=borderwidth)
+    entry.pack(side=LEFT, fill=X, expand=1)
+
+    return entry, frame
+
+# This is a slightly modified version of the function above.  This
+# version does the proper alighnment of labels with their fields.  It
+# should probably eventually replace make_form_entry altogether.
+#
+# The one annoying bug is that the text entry field should be
+# expandable while still aligning the colons.  This doesn't work yet.
+#
+def make_labeled_form_entry(parent, label, entrywidth=20, entryheight=1,
+			    labelwidth=0, borderwidth=None,
+			    takefocus=None):
+    """Subroutine to create a form entry.
+
+    Create:
+    - a horizontally filling and expanding frame, containing:
+      - a label on the left, and
+      - a text entry on the right.
+
+    Return the entry widget and the frame widget.
+    """
+    if label and label[-1] != ':': label = label + ':'
+
+    frame = Frame(parent)
+
+    label = Label(frame, text=label, width=labelwidth, anchor=E)
+    label.pack(side=LEFT)
+    if entryheight == 1:
+	if borderwidth is None:
+	    entry = Entry(frame, relief=SUNKEN, width=entrywidth)
+	else:
+	    entry = Entry(frame, relief=SUNKEN, width=entrywidth,
+			  borderwidth=borderwidth)
+	entry.pack(side=RIGHT, expand=1, fill=X)
+	frame.pack(fill=X)
+    else:
+	entry = make_text_box(frame, entrywidth, entryheight, 1, 1,
+			      takefocus=takefocus)
+	frame.pack(fill=BOTH, expand=1)
+
+    return entry, frame, label
+
+
+def make_double_frame(master=None, class_=None, name=None, relief=RAISED,
+		      borderwidth=1):
+    """Create a pair of frames suitable for 'hosting' a dialog."""
+    if name:
+	if class_: frame = Frame(master, class_=class_, name=name)
+	else: frame = Frame(master, name=name)
+    else:
+	if class_: frame = Frame(master, class_=class_)
+	else: frame = Frame(master)
+    top = Frame(frame, name="topframe", relief=relief,
+		borderwidth=borderwidth)
+    bottom = Frame(frame, name="bottomframe")
+    bottom.pack(fill=X, padx='1m', pady='1m', side=BOTTOM)
+    top.pack(expand=1, fill=BOTH, padx='1m', pady='1m')
+    frame.pack(expand=1, fill=BOTH)
+    top = Frame(top)
+    top.pack(expand=1, fill=BOTH, padx='2m', pady='2m')
+
+    return frame, top, bottom
+
+
+def make_group_frame(master, name=None, label=None, fill=Y,
+		     side=None, expand=None, font=None):
+    """Create nested frames with a border and optional label.
+
+    The outer frame is only used to provide the decorative border, to
+    control packing, and to host the label.  The inner frame is packed
+    to fill the outer frame and should be used as the parent of all
+    sub-widgets.  Only the inner frame is returned.
+
+    """
+    font = font or "-*-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*"
+    outer = Frame(master, borderwidth=2, relief=GROOVE)
+    outer.pack(expand=expand, fill=fill, side=side)
+    if label:
+	Label(outer, text=label, font=font, anchor=W).pack(fill=X)
+    inner = Frame(master, borderwidth='1m', name=name)
+    inner.pack(expand=1, fill=BOTH, in_=outer)
+    inner.forget = outer.forget
+    return inner
+
+
+def unify_button_widths(*buttons):
+    """Make buttons passed in all have the same width.
+
+    Works for labels and other widgets with the 'text' option.
+
+    """
+    wid = 0
+    for btn in buttons:
+	wid = max(wid, len(btn["text"]))
+    for btn in buttons:
+	btn["width"] = wid
+
+
+def flatten(msg):
+    """Turn a list or tuple into a single string -- recursively."""
+    t = type(msg)
+    if t in (ListType, TupleType):
+	msg = string.join(map(flatten, msg))
+    elif t is ClassType:
+	msg = msg.__name__
+    else:
+	msg = str(msg)
+    return msg
+
+
+def boolean(s):
+    """Test whether a string is a Tk boolean, without error checking."""
+    if string.lower(s) in ('', '0', 'no', 'off', 'false'): return 0
+    else: return 1
+
+
+def test():
+    """Test make_text_box(), make_form_entry(), flatten(), boolean()."""
+    import sys
+    root = Tk()
+    entry, eframe = make_form_entry(root, 'Boolean:')
+    text, tframe = make_text_box(root)
+    def enter(event, entry=entry, text=text):
+	s = boolean(entry.get()) and '\nyes' or '\nno'
+	text.insert('end', s)
+    entry.bind('<Return>', enter)
+    entry.insert(END, flatten(sys.argv))
+    root.mainloop()
+
+
+if __name__ == '__main__':
+    test()
