diff --git a/Lib/idlelib/AutoCompleteWindow.py b/Lib/idlelib/AutoCompleteWindow.py
index ab132c1..635775d 100644
--- a/Lib/idlelib/AutoCompleteWindow.py
+++ b/Lib/idlelib/AutoCompleteWindow.py
@@ -1,7 +1,7 @@
 """
 An auto-completion window for IDLE, used by the AutoComplete extension
 """
-from tkinter import *
+from Tkinter import *
 from MultiCall import MC_SHIFT
 import AutoComplete
 
diff --git a/Lib/idlelib/CallTipWindow.py b/Lib/idlelib/CallTipWindow.py
index 27ed085..2223885 100644
--- a/Lib/idlelib/CallTipWindow.py
+++ b/Lib/idlelib/CallTipWindow.py
@@ -4,7 +4,7 @@
 Used by the CallTips IDLE extension.
 
 """
-from tkinter import *
+from Tkinter import *
 
 HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
 HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
diff --git a/Lib/idlelib/CodeContext.py b/Lib/idlelib/CodeContext.py
index 941bb26..420ec33 100644
--- a/Lib/idlelib/CodeContext.py
+++ b/Lib/idlelib/CodeContext.py
@@ -9,8 +9,8 @@
 not open blocks are not shown in the context hints pane.
 
 """
-import tkinter
-from tkinter.constants import TOP, LEFT, X, W, SUNKEN
+import Tkinter
+from Tkconstants import TOP, LEFT, X, W, SUNKEN
 from configHandler import idleConf
 import re
 from sys import maxint as INFINITY
@@ -69,7 +69,7 @@
             border = 0
             for widget in widgets:
                 border += int(str( widget.cget('border') ))
-            self.label = tkinter.Label(self.editwin.top,
+            self.label = Tkinter.Label(self.editwin.top,
                                        text="\n" * (self.context_depth - 1),
                                        anchor=W, justify=LEFT,
                                        font=self.textfont,
diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py
index fb84805..e55f9e6 100644
--- a/Lib/idlelib/ColorDelegator.py
+++ b/Lib/idlelib/ColorDelegator.py
@@ -2,7 +2,7 @@
 import re
 import keyword
 import __builtin__
-from tkinter import *
+from Tkinter import *
 from Delegator import Delegator
 from configHandler import idleConf
 
diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py
index fa2a56b..a56c224 100644
--- a/Lib/idlelib/Debugger.py
+++ b/Lib/idlelib/Debugger.py
@@ -1,7 +1,7 @@
 import os
 import bdb
 import types
-from tkinter import *
+from Tkinter import *
 from WindowList import ListedToplevel
 from ScrolledList import ScrolledList
 import macosxSupport
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index 2f728b3..8d35198c 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -3,9 +3,9 @@
 import re
 import imp
 from itertools import count
-from tkinter import *
-import tkinter.simpledialog as tkSimpleDialog
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkSimpleDialog
+import tkMessageBox
 from MultiCall import MultiCallCreator
 
 import webbrowser
@@ -45,7 +45,7 @@
     from UndoDelegator import UndoDelegator
     from IOBinding import IOBinding, filesystemencoding, encoding
     import Bindings
-    from tkinter import Toplevel
+    from Tkinter import Toplevel
     from MultiStatusBar import MultiStatusBar
 
     help_url = None
diff --git a/Lib/idlelib/FileList.py b/Lib/idlelib/FileList.py
index 4520334..e40c7a7 100644
--- a/Lib/idlelib/FileList.py
+++ b/Lib/idlelib/FileList.py
@@ -1,6 +1,6 @@
 import os
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkMessageBox
 
 
 class FileList:
diff --git a/Lib/idlelib/GrepDialog.py b/Lib/idlelib/GrepDialog.py
index ccee522..ab136bc 100644
--- a/Lib/idlelib/GrepDialog.py
+++ b/Lib/idlelib/GrepDialog.py
@@ -1,7 +1,7 @@
 import os
 import fnmatch
 import sys
-from tkinter import *
+from Tkinter import *
 import SearchEngine
 from SearchDialogBase import SearchDialogBase
 
diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py
index e18ff3f..01d278e 100644
--- a/Lib/idlelib/IOBinding.py
+++ b/Lib/idlelib/IOBinding.py
@@ -10,11 +10,11 @@
 import sys
 import codecs
 import tempfile
-import tkinter.filedialog as tkFileDialog
-import tkinter.messagebox as tkMessageBox
+import tkFileDialog
+import tkMessageBox
 import re
-from tkinter import *
-from tkinter.simpledialog import SimpleDialog
+from Tkinter import *
+from SimpleDialog import SimpleDialog
 
 from configHandler import idleConf
 
diff --git a/Lib/idlelib/MultiCall.py b/Lib/idlelib/MultiCall.py
index 269ab3f..51de639 100644
--- a/Lib/idlelib/MultiCall.py
+++ b/Lib/idlelib/MultiCall.py
@@ -32,7 +32,7 @@
 import sys
 import string
 import re
-import tkinter
+import Tkinter
 
 # the event type constants, which define the meaning of mc_type
 MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3;
@@ -292,7 +292,7 @@
         return _multicall_dict[widget]
 
     class MultiCall (widget):
-        assert issubclass(widget, tkinter.Misc)
+        assert issubclass(widget, Tkinter.Misc)
 
         def __init__(self, *args, **kwargs):
             apply(widget.__init__, (self,)+args, kwargs)
@@ -382,8 +382,8 @@
 
 if __name__ == "__main__":
     # Test
-    root = tkinter.Tk()
-    text = MultiCallCreator(tkinter.Text)(root)
+    root = Tkinter.Tk()
+    text = MultiCallCreator(Tkinter.Text)(root)
     text.pack()
     def bindseq(seq, n=[0]):
         def handler(event):
diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py
index dadc42d..2d4c547 100644
--- a/Lib/idlelib/MultiStatusBar.py
+++ b/Lib/idlelib/MultiStatusBar.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 
 class MultiStatusBar(Frame):
 
diff --git a/Lib/idlelib/ObjectBrowser.py b/Lib/idlelib/ObjectBrowser.py
index c328cdc..8ff0041 100644
--- a/Lib/idlelib/ObjectBrowser.py
+++ b/Lib/idlelib/ObjectBrowser.py
@@ -136,7 +136,7 @@
 
 def _test():
     import sys
-    from tkinter import Tk
+    from Tkinter import Tk
     root = Tk()
     root.configure(bd=0, bg="yellow")
     root.focus_set()
diff --git a/Lib/idlelib/OutputWindow.py b/Lib/idlelib/OutputWindow.py
index afc4e39..787e9b0 100644
--- a/Lib/idlelib/OutputWindow.py
+++ b/Lib/idlelib/OutputWindow.py
@@ -1,7 +1,7 @@
-from tkinter import *
+from Tkinter import *
 from EditorWindow import EditorWindow
 import re
-import tkinter.messagebox as tkMessageBox
+import tkMessageBox
 import IOBinding
 
 class OutputWindow(EditorWindow):
diff --git a/Lib/idlelib/Percolator.py b/Lib/idlelib/Percolator.py
index 21d8a47..ebbcba9 100644
--- a/Lib/idlelib/Percolator.py
+++ b/Lib/idlelib/Percolator.py
@@ -81,5 +81,5 @@
     root.mainloop()
 
 if __name__ == "__main__":
-    from tkinter import *
+    from Tkinter import *
     main()
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 4754866..a17f81f 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -17,12 +17,12 @@
 from code import InteractiveInterpreter
 
 try:
-    from tkinter import *
+    from Tkinter import *
 except ImportError:
-    print>>sys.__stderr__, "** IDLE can't import tkinter.  " \
+    print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
                            "Your Python may not be configured for Tk. **"
     sys.exit(1)
-import tkinter.messagebox as tkMessageBox
+import tkMessageBox
 
 from EditorWindow import EditorWindow, fixwordbreaks
 from FileList import FileList
@@ -992,8 +992,8 @@
                    (sys.version, sys.platform, self.COPYRIGHT,
                     self.firewallmessage, idlever.IDLE_VERSION, nosub))
         self.showprompt()
-        import tkinter
-        tkinter._default_root = None # 03Jan04 KBK What's this?
+        import Tkinter
+        Tkinter._default_root = None # 03Jan04 KBK What's this?
         return True
 
     def readline(self):
diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py
index c8f6784..c8eb1c8 100644
--- a/Lib/idlelib/ReplaceDialog.py
+++ b/Lib/idlelib/ReplaceDialog.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 import SearchEngine
 from SearchDialogBase import SearchDialogBase
 
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
index c6892f3..cb01110 100644
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -22,7 +22,7 @@
 import string
 import tabnanny
 import tokenize
-import tkinter.messagebox as tkMessageBox
+import tkMessageBox
 import PyShell
 
 from configHandler import idleConf
diff --git a/Lib/idlelib/ScrolledList.py b/Lib/idlelib/ScrolledList.py
index f923488..9211936 100644
--- a/Lib/idlelib/ScrolledList.py
+++ b/Lib/idlelib/ScrolledList.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 
 class ScrolledList:
 
diff --git a/Lib/idlelib/SearchDialog.py b/Lib/idlelib/SearchDialog.py
index 6c90d28..d7124d6 100644
--- a/Lib/idlelib/SearchDialog.py
+++ b/Lib/idlelib/SearchDialog.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 import SearchEngine
 from SearchDialogBase import SearchDialogBase
 
diff --git a/Lib/idlelib/SearchDialogBase.py b/Lib/idlelib/SearchDialogBase.py
index 65914ac..f63e7ae 100644
--- a/Lib/idlelib/SearchDialogBase.py
+++ b/Lib/idlelib/SearchDialogBase.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 
 class SearchDialogBase:
 
diff --git a/Lib/idlelib/SearchEngine.py b/Lib/idlelib/SearchEngine.py
index 2d05af8..cc40a00 100644
--- a/Lib/idlelib/SearchEngine.py
+++ b/Lib/idlelib/SearchEngine.py
@@ -1,6 +1,6 @@
 import re
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkMessageBox
 
 def get(root):
     if not hasattr(root, "_searchengine"):
diff --git a/Lib/idlelib/StackViewer.py b/Lib/idlelib/StackViewer.py
index 794726d..6b7730b 100644
--- a/Lib/idlelib/StackViewer.py
+++ b/Lib/idlelib/StackViewer.py
@@ -7,7 +7,7 @@
 
 def StackBrowser(root, flist=None, tb=None, top=None):
     if top is None:
-        from tkinter import Toplevel
+        from Tkinter import Toplevel
         top = Toplevel(root)
     sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
     sc.frame.pack(expand=1, fill="both")
@@ -128,7 +128,7 @@
         reload(testcode)
     except:
         sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info()
-    from tkinter import Tk
+    from Tkinter import Tk
     root = Tk()
     StackBrowser(None, top=root)
     root.mainloop()
diff --git a/Lib/idlelib/ToolTip.py b/Lib/idlelib/ToolTip.py
index b178803..ce7a3d3 100644
--- a/Lib/idlelib/ToolTip.py
+++ b/Lib/idlelib/ToolTip.py
@@ -3,7 +3,7 @@
 # may be useful for some purposes in (or almost in ;) the current project scope
 # Ideas gleaned from PySol
 
-from tkinter import *
+from Tkinter import *
 
 class ToolTipBase:
 
diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py
index 876cb0d..5299e0e 100644
--- a/Lib/idlelib/TreeWidget.py
+++ b/Lib/idlelib/TreeWidget.py
@@ -15,7 +15,7 @@
 # - optimize tree redraw after expand of subnode
 
 import os
-from tkinter import *
+from Tkinter import *
 import imp
 
 import ZoomHeight
diff --git a/Lib/idlelib/UndoDelegator.py b/Lib/idlelib/UndoDelegator.py
index 544be10..5896bd5 100644
--- a/Lib/idlelib/UndoDelegator.py
+++ b/Lib/idlelib/UndoDelegator.py
@@ -1,5 +1,5 @@
 import string
-from tkinter import *
+from Tkinter import *
 from Delegator import Delegator
 
 #$ event <<redo>>
diff --git a/Lib/idlelib/WidgetRedirector.py b/Lib/idlelib/WidgetRedirector.py
index a87e650..7c341f2 100644
--- a/Lib/idlelib/WidgetRedirector.py
+++ b/Lib/idlelib/WidgetRedirector.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 
 class WidgetRedirector:
 
diff --git a/Lib/idlelib/WindowList.py b/Lib/idlelib/WindowList.py
index ccf35a8..658502b 100644
--- a/Lib/idlelib/WindowList.py
+++ b/Lib/idlelib/WindowList.py
@@ -1,4 +1,4 @@
-from tkinter import *
+from Tkinter import *
 
 class WindowList:
 
diff --git a/Lib/idlelib/aboutDialog.py b/Lib/idlelib/aboutDialog.py
index 4900c09..008602c 100644
--- a/Lib/idlelib/aboutDialog.py
+++ b/Lib/idlelib/aboutDialog.py
@@ -2,7 +2,7 @@
 
 """
 
-from tkinter import *
+from Tkinter import *
 import os
 import os.path
 import textView
diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py
index 68cc3fe..acab053 100644
--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -9,10 +9,8 @@
 Refer to comments in EditorWindow autoindent code for details.
 
 """
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
-import tkinter.colorchooser as tkColorChooser
-import tkinter.font as tkFont
+from Tkinter import *
+import tkMessageBox, tkColorChooser, tkFont
 import string
 
 from configHandler import idleConf
diff --git a/Lib/idlelib/configHelpSourceEdit.py b/Lib/idlelib/configHelpSourceEdit.py
index b80c548..6611621 100644
--- a/Lib/idlelib/configHelpSourceEdit.py
+++ b/Lib/idlelib/configHelpSourceEdit.py
@@ -3,9 +3,9 @@
 import os
 import sys
 
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
-import tkinter.filedialog as tkFileDialog
+from Tkinter import *
+import tkMessageBox
+import tkFileDialog
 
 class GetHelpSourceDialog(Toplevel):
     def __init__(self, parent, title, menuItem='', filePath=''):
diff --git a/Lib/idlelib/configSectionNameDialog.py b/Lib/idlelib/configSectionNameDialog.py
index bcf132c..4f1b002 100644
--- a/Lib/idlelib/configSectionNameDialog.py
+++ b/Lib/idlelib/configSectionNameDialog.py
@@ -2,8 +2,8 @@
 Dialog that allows user to specify a new config file section name.
 Used to get new highlight theme and keybinding set names.
 """
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkMessageBox
 
 class GetCfgSectionNameDialog(Toplevel):
     def __init__(self,parent,title,message,usedNames):
diff --git a/Lib/idlelib/dynOptionMenuWidget.py b/Lib/idlelib/dynOptionMenuWidget.py
index 90fc323..e81f7ba 100644
--- a/Lib/idlelib/dynOptionMenuWidget.py
+++ b/Lib/idlelib/dynOptionMenuWidget.py
@@ -2,8 +2,8 @@
 OptionMenu widget modified to allow dynamic menu reconfiguration
 and setting of highlightthickness
 """
-from tkinter import OptionMenu
-from tkinter import _setit
+from Tkinter import OptionMenu
+from Tkinter import _setit
 import copy
 
 class DynOptionMenu(OptionMenu):
diff --git a/Lib/idlelib/keybindingDialog.py b/Lib/idlelib/keybindingDialog.py
index e58ac73..1ce7ff4 100644
--- a/Lib/idlelib/keybindingDialog.py
+++ b/Lib/idlelib/keybindingDialog.py
@@ -1,8 +1,8 @@
 """
 Dialog for building Tkinter accelerator key bindings
 """
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkMessageBox
 import string
 
 class GetKeysDialog(Toplevel):
diff --git a/Lib/idlelib/macosxSupport.py b/Lib/idlelib/macosxSupport.py
index c76381d..222abfc 100644
--- a/Lib/idlelib/macosxSupport.py
+++ b/Lib/idlelib/macosxSupport.py
@@ -3,7 +3,7 @@
 GUI application (as opposed to an X11 application).
 """
 import sys
-import tkinter
+import Tkinter
 
 def runningAsOSXApp():
     """ Returns True iff running from the IDLE.app bundle on OSX """
@@ -26,7 +26,7 @@
 def hideTkConsole(root):
     try:
         root.tk.call('console', 'hide')
-    except tkinter.TclError:
+    except Tkinter.TclError:
         # Some versions of the Tk framework don't have a console object
         pass
 
@@ -46,7 +46,7 @@
     #
     # Due to a (mis-)feature of TkAqua the user will also see an empty Help
     # menu.
-    from tkinter import Menu, Text, Text
+    from Tkinter import Menu, Text, Text
     from EditorWindow import prepstr, get_accelerator
     import Bindings
     import WindowList
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
index 18ddca7..8abbe50 100644
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -127,9 +127,9 @@
     server.handle_request() # A single request only
 
 def show_socket_error(err, address):
-    import tkinter
-    import tkinter.messagebox as tkMessageBox
-    root = tkinter.Tk()
+    import Tkinter
+    import tkMessageBox
+    root = Tkinter.Tk()
     root.withdraw()
     if err[0] == 61: # connection refused
         msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py
index 429af5d..8d7113d 100644
--- a/Lib/idlelib/tabbedpages.py
+++ b/Lib/idlelib/tabbedpages.py
@@ -7,7 +7,7 @@
 TabSet -- A widget containing tabs (buttons) in one or more rows.
 
 """
-from tkinter import *
+from Tkinter import *
 
 class InvalidNameError(Exception): pass
 class AlreadyExistsError(Exception): pass
diff --git a/Lib/idlelib/textView.py b/Lib/idlelib/textView.py
index 3f3c247..0e7e663 100644
--- a/Lib/idlelib/textView.py
+++ b/Lib/idlelib/textView.py
@@ -2,8 +2,8 @@
 
 """
 
-from tkinter import *
-import tkinter.messagebox as tkMessageBox
+from Tkinter import *
+import tkMessageBox
 
 class TextViewer(Toplevel):
     """A simple text viewer dialog for IDLE
@@ -68,7 +68,7 @@
         else:
             textFile = open(filename, 'r')
     except IOError:
-        import tkinter.messagebox as tkMessageBox
+        import tkMessageBox
         tkMessageBox.showerror(title='File Load Error',
                                message='Unable to load file %r .' % filename,
                                parent=parent)
diff --git a/Lib/lib-tk/Canvas.py b/Lib/lib-tk/Canvas.py
index d35b1f5..34464ab 100644
--- a/Lib/lib-tk/Canvas.py
+++ b/Lib/lib-tk/Canvas.py
@@ -7,7 +7,7 @@
 warnpy3k("the Canvas module has been removed in Python 3.0", stacklevel=2)
 del warnpy3k
 
-from tkinter import Canvas, _cnfmerge, _flatten
+from Tkinter import Canvas, _cnfmerge, _flatten
 
 
 class CanvasItem:
diff --git a/Lib/lib-tk/Dialog.py b/Lib/lib-tk/Dialog.py
index 75e7fed..2d08959 100644
--- a/Lib/lib-tk/Dialog.py
+++ b/Lib/lib-tk/Dialog.py
@@ -1,7 +1,7 @@
 # dialog.py -- Tkinter interface to the tk_dialog script.
 
-from tkinter import *
-from tkinter import _cnfmerge
+from Tkinter import *
+from Tkinter import _cnfmerge
 
 if TkVersion <= 3.6:
     DIALOG_ICON = 'warning'
diff --git a/Lib/lib-tk/ScrolledText.py b/Lib/lib-tk/ScrolledText.py
index c96bc3b..367aa89 100644
--- a/Lib/lib-tk/ScrolledText.py
+++ b/Lib/lib-tk/ScrolledText.py
@@ -10,8 +10,8 @@
 # Most methods calls are inherited from the Text widget; Pack methods
 # are redirected to the Frame widget however.
 
-from tkinter import *
-from tkinter import _cnfmerge
+from Tkinter import *
+from Tkinter import _cnfmerge
 
 class ScrolledText(Text):
     def __init__(self, master=None, cnf=None, **kw):
diff --git a/Lib/lib-tk/Tix.py b/Lib/lib-tk/Tix.py
index 22a9000..b7a0fc0 100755
--- a/Lib/lib-tk/Tix.py
+++ b/Lib/lib-tk/Tix.py
@@ -26,8 +26,8 @@
 # appreciate the advantages.
 #
 
-from tkinter import *
-from tkinter import _flatten, _cnfmerge, _default_root
+from Tkinter import *
+from Tkinter import _flatten, _cnfmerge, _default_root
 
 # WARNING - TkVersion is a limited precision floating point number
 if TkVersion < 3.999:
@@ -57,7 +57,7 @@
 # BEWARE - this is implemented by copying some code from the Widget class
 #          in Tkinter (to override Widget initialization) and is therefore
 #          liable to break.
-import tkinter, os
+import Tkinter, os
 
 # Could probably add this to Tkinter.Misc
 class tixCommand:
@@ -192,11 +192,11 @@
         else:
             return self.tk.call('tix', 'resetoptions', newScheme, newFontSet)
 
-class Tk(tkinter.Tk, tixCommand):
+class Tk(Tkinter.Tk, tixCommand):
     """Toplevel widget of Tix which represents mostly the main window
     of an application. It has an associated Tcl interpreter."""
     def __init__(self, screenName=None, baseName=None, className='Tix'):
-        tkinter.Tk.__init__(self, screenName, baseName, className)
+        Tkinter.Tk.__init__(self, screenName, baseName, className)
         tixlib = os.environ.get('TIX_LIBRARY')
         self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]')
         if tixlib is not None:
@@ -212,7 +212,7 @@
     def destroy(self):
         # For safety, remove an delete_window binding before destroy
         self.protocol("WM_DELETE_WINDOW", "")
-        tkinter.Tk.destroy(self)
+        Tkinter.Tk.destroy(self)
 
 # The Tix 'tixForm' geometry manager
 class Form:
@@ -260,9 +260,9 @@
 
 
 
-tkinter.Widget.__bases__ = tkinter.Widget.__bases__ + (Form,)
+Tkinter.Widget.__bases__ = Tkinter.Widget.__bases__ + (Form,)
 
-class TixWidget(tkinter.Widget):
+class TixWidget(Tkinter.Widget):
     """A TixWidget class is used to package all (or most) Tix widgets.
 
     Widget initialization is extended in two ways:
@@ -383,7 +383,7 @@
     # These are missing from Tkinter
     def image_create(self, imgtype, cnf={}, master=None, **kw):
         if not master:
-            master = tkinter._default_root
+            master = Tkinter._default_root
             if not master:
                 raise RuntimeError, 'Too early to create image'
         if kw and cnf: cnf = _cnfmerge((cnf, kw))
diff --git a/Lib/lib-tk/Tkdnd.py b/Lib/lib-tk/Tkdnd.py
index 55f0776..2e37d9e 100644
--- a/Lib/lib-tk/Tkdnd.py
+++ b/Lib/lib-tk/Tkdnd.py
@@ -100,7 +100,7 @@
 """
 
 
-import tkinter
+import Tkinter
 
 
 # The factory function
@@ -219,7 +219,7 @@
             self.detach()
         if not canvas:
             return
-        label = tkinter.Label(canvas, text=self.name,
+        label = Tkinter.Label(canvas, text=self.name,
                               borderwidth=2, relief="raised")
         id = canvas.create_window(x, y, window=label, anchor="nw")
         self.canvas = canvas
@@ -268,8 +268,8 @@
 class Tester:
 
     def __init__(self, root):
-        self.top = tkinter.Toplevel(root)
-        self.canvas = tkinter.Canvas(self.top, width=100, height=100)
+        self.top = Tkinter.Toplevel(root)
+        self.canvas = Tkinter.Canvas(self.top, width=100, height=100)
         self.canvas.pack(fill="both", expand=1)
         self.canvas.dnd_accept = self.dnd_accept
 
@@ -300,9 +300,9 @@
         source.attach(self.canvas, x, y)
 
 def test():
-    root = tkinter.Tk()
+    root = Tkinter.Tk()
     root.geometry("+1+1")
-    tkinter.Button(command=root.quit, text="Quit").pack()
+    Tkinter.Button(command=root.quit, text="Quit").pack()
     t1 = Tester(root)
     t1.top.geometry("+1+60")
     t2 = Tester(root)
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index d83b2ba..dccabad 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -18,14 +18,14 @@
 command) or with the method bind.
 
 Example (Hello, World):
-import tkinter
-from tkinter.constants import *
-tk = tkinter.Tk()
-frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
+import Tkinter
+from Tkconstants import *
+tk = Tkinter.Tk()
+frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
 frame.pack(fill=BOTH,expand=1)
-label = tkinter.Label(frame, text="Hello, World")
+label = Tkinter.Label(frame, text="Hello, World")
 label.pack(fill=X, expand=1)
-button = tkinter.Button(frame,text="Exit",command=tk.destroy)
+button = Tkinter.Button(frame,text="Exit",command=tk.destroy)
 button.pack(side=BOTTOM)
 tk.mainloop()
 """
@@ -35,11 +35,12 @@
 import sys
 if sys.platform == "win32":
     # Attempt to configure Tcl/Tk without requiring PATH
-    from tkinter import _fix
+    import FixTk
 import _tkinter # If this fails your Python may not be configured for Tk
+tkinter = _tkinter # b/w compat for export
 TclError = _tkinter.TclError
 from types import *
-from tkinter.constants import *
+from Tkconstants import *
 try:
     import MacOS; _MacOS = MacOS; del MacOS
 except ImportError:
@@ -1697,7 +1698,7 @@
         base_tcl = os.path.join(home, '.%s.tcl' % baseName)
         base_py = os.path.join(home, '.%s.py' % baseName)
         dir = {'self': self}
-        exec 'from tkinter import *' in dir
+        exec 'from Tkinter import *' in dir
         if os.path.isfile(class_tcl):
             self.tk.call('source', class_tcl)
         if os.path.isfile(class_py):
diff --git a/Lib/lib-tk/tkColorChooser.py b/Lib/lib-tk/tkColorChooser.py
index 77b391a..a55a797 100644
--- a/Lib/lib-tk/tkColorChooser.py
+++ b/Lib/lib-tk/tkColorChooser.py
@@ -19,7 +19,7 @@
 # - title: dialog title
 #
 
-from tkinter.commondialog import Dialog
+from tkCommonDialog import Dialog
 
 
 #
diff --git a/Lib/lib-tk/tkCommonDialog.py b/Lib/lib-tk/tkCommonDialog.py
index f61eb45..2cd9be4 100644
--- a/Lib/lib-tk/tkCommonDialog.py
+++ b/Lib/lib-tk/tkCommonDialog.py
@@ -1,14 +1,14 @@
 # base class for tk common dialogues
 #
 # this module provides a base class for accessing the common
-# dialogues available in Tk 4.2 and newer.  use filedialog,
-# colorchooser, and messagebox to access the individual
+# dialogues available in Tk 4.2 and newer.  use tkFileDialog,
+# tkColorChooser, and tkMessageBox to access the individual
 # dialogs.
 #
 # written by Fredrik Lundh, May 1997
 #
 
-from tkinter import *
+from Tkinter import *
 
 class Dialog:
 
diff --git a/Lib/lib-tk/tkFont.py b/Lib/lib-tk/tkFont.py
index c23f047..229f251 100644
--- a/Lib/lib-tk/tkFont.py
+++ b/Lib/lib-tk/tkFont.py
@@ -8,7 +8,7 @@
 
 __version__ = "0.9"
 
-import tkinter
+import Tkinter
 
 # weight/slant
 NORMAL = "normal"
@@ -31,7 +31,7 @@
     name -- name to use for this font configuration (defaults to a unique name)
     exists -- does a named font by this name already exist?
        Creates a new named font if False, points to the existing font if True.
-       Raises _tkinter.TclError if the assertion is false.
+       Raises _Tkinter.TclError if the assertion is false.
 
        the following are ignored if font is specified:
 
@@ -65,7 +65,7 @@
 
     def __init__(self, root=None, font=None, name=None, exists=False, **options):
         if not root:
-            root = tkinter._default_root
+            root = Tkinter._default_root
         if font:
             # get actual settings corresponding to the given font
             font = root.tk.splitlist(root.tk.call("font", "actual", font))
@@ -79,7 +79,7 @@
             self.delete_font = False
             # confirm font exists
             if self.name not in root.tk.call("font", "names"):
-                raise tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,)
+                raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,)
             # if font config info supplied, apply it
             if font:
                 root.tk.call("font", "configure", self.name, *font)
@@ -166,13 +166,13 @@
 def families(root=None):
     "Get font families (as a tuple)"
     if not root:
-        root = tkinter._default_root
+        root = Tkinter._default_root
     return root.tk.splitlist(root.tk.call("font", "families"))
 
 def names(root=None):
     "Get names of defined fonts (as a tuple)"
     if not root:
-        root = tkinter._default_root
+        root = Tkinter._default_root
     return root.tk.splitlist(root.tk.call("font", "names"))
 
 # --------------------------------------------------------------------
@@ -180,7 +180,7 @@
 
 if __name__ == "__main__":
 
-    root = tkinter.Tk()
+    root = Tkinter.Tk()
 
     # create a font
     f = Font(family="times", size=30, weight=NORMAL)
@@ -202,10 +202,10 @@
     f = Font(font=("Courier", 20, "bold"))
     print f.measure("hello"), f.metrics("linespace")
 
-    w = tkinter.Label(root, text="Hello, world", font=f)
+    w = Tkinter.Label(root, text="Hello, world", font=f)
     w.pack()
 
-    w = tkinter.Button(root, text="Quit!", command=root.destroy)
+    w = Tkinter.Button(root, text="Quit!", command=root.destroy)
     w.pack()
 
     fb = Font(font=w["font"]).copy()
@@ -213,4 +213,4 @@
 
     w.config(font=fb)
 
-    tkinter.mainloop()
+    Tkinter.mainloop()
diff --git a/Lib/lib-tk/tkMessageBox.py b/Lib/lib-tk/tkMessageBox.py
index df0a163..8f7483f 100644
--- a/Lib/lib-tk/tkMessageBox.py
+++ b/Lib/lib-tk/tkMessageBox.py
@@ -22,7 +22,7 @@
 # - type: dialog type; that is, which buttons to display (see below)
 #
 
-from tkinter.commondialog import Dialog
+from Tkinter.commondialog import Dialog
 
 #
 # constants
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 0d343e6..e4cac29 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -16,7 +16,7 @@
 
 from math import * # Also for export
 from time import sleep
-import tkinter
+import Tkinter
 
 speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
 
@@ -238,7 +238,7 @@
                 # Test the color first
                 try:
                     id = self._canvas.create_line(0, 0, 0, 0, fill=color)
-                except tkinter.TclError:
+                except Tkinter.TclError:
                     raise Error, "bad color string: %r" % (color,)
                 self._set_color(color)
                 return
@@ -554,7 +554,7 @@
                     # in case nhops==0
                     self._canvas.coords(item, x0, y0, x1, y1)
                     self._canvas.itemconfigure(item, arrow="none")
-                except tkinter.TclError:
+                except Tkinter.TclError:
                     # Probably the window was closed!
                     return
             else:
@@ -638,13 +638,13 @@
     def __init__(self):
         global _root, _canvas
         if _root is None:
-            _root = tkinter.Tk()
+            _root = Tkinter.Tk()
             _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
             _root.title(_title)
 
         if _canvas is None:
             # XXX Should have scroll bars
-            _canvas = tkinter.Canvas(_root, background="white")
+            _canvas = Tkinter.Canvas(_root, background="white")
             _canvas.pack(expand=1, fill="both")
 
             setup(width=_width, height= _height, startx=_startx, starty=_starty)
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index bdfc942..987d213 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -2017,20 +2017,20 @@
             self.server = None
             self.scanner = None
 
-            import tkinter
-            self.server_frm = tkinter.Frame(window)
-            self.title_lbl = tkinter.Label(self.server_frm,
+            import Tkinter
+            self.server_frm = Tkinter.Frame(window)
+            self.title_lbl = Tkinter.Label(self.server_frm,
                 text='Starting server...\n ')
-            self.open_btn = tkinter.Button(self.server_frm,
+            self.open_btn = Tkinter.Button(self.server_frm,
                 text='open browser', command=self.open, state='disabled')
-            self.quit_btn = tkinter.Button(self.server_frm,
+            self.quit_btn = Tkinter.Button(self.server_frm,
                 text='quit serving', command=self.quit, state='disabled')
 
-            self.search_frm = tkinter.Frame(window)
-            self.search_lbl = tkinter.Label(self.search_frm, text='Search for')
-            self.search_ent = tkinter.Entry(self.search_frm)
+            self.search_frm = Tkinter.Frame(window)
+            self.search_lbl = Tkinter.Label(self.search_frm, text='Search for')
+            self.search_ent = Tkinter.Entry(self.search_frm)
             self.search_ent.bind('<Return>', self.search)
-            self.stop_btn = tkinter.Button(self.search_frm,
+            self.stop_btn = Tkinter.Button(self.search_frm,
                 text='stop', pady=0, command=self.stop, state='disabled')
             if sys.platform == 'win32':
                 # Trying to hide and show this button crashes under Windows.
@@ -2049,17 +2049,17 @@
             self.search_ent.focus_set()
 
             font = ('helvetica', sys.platform == 'win32' and 8 or 10)
-            self.result_lst = tkinter.Listbox(window, font=font, height=6)
+            self.result_lst = Tkinter.Listbox(window, font=font, height=6)
             self.result_lst.bind('<Button-1>', self.select)
             self.result_lst.bind('<Double-Button-1>', self.goto)
-            self.result_scr = tkinter.Scrollbar(window,
+            self.result_scr = Tkinter.Scrollbar(window,
                 orient='vertical', command=self.result_lst.yview)
             self.result_lst.config(yscrollcommand=self.result_scr.set)
 
-            self.result_frm = tkinter.Frame(window)
-            self.goto_btn = tkinter.Button(self.result_frm,
+            self.result_frm = Tkinter.Frame(window)
+            self.goto_btn = Tkinter.Button(self.result_frm,
                 text='go to selected', command=self.goto)
-            self.hide_btn = tkinter.Button(self.result_frm,
+            self.hide_btn = Tkinter.Button(self.result_frm,
                 text='hide results', command=self.hide)
             self.goto_btn.pack(side='left', fill='x', expand=1)
             self.hide_btn.pack(side='right', fill='x', expand=1)
@@ -2179,9 +2179,9 @@
             self.stop()
             self.collapse()
 
-    import tkinter
+    import Tkinter
     try:
-        root = tkinter.Tk()
+        root = Tkinter.Tk()
         # Tk will crash if pythonw.exe has an XP .manifest
         # file and the root has is not destroyed explicitly.
         # If the problem is ever fixed in Tk, the explicit
diff --git a/Lib/test/test_py3kwarn.py b/Lib/test/test_py3kwarn.py
index eb28b89..0641f7d 100644
--- a/Lib/test/test_py3kwarn.py
+++ b/Lib/test/test_py3kwarn.py
@@ -218,23 +218,7 @@
     renames = {'copy_reg': 'copyreg', 'Queue': 'queue',
                'SocketServer': 'socketserver',
                'ConfigParser': 'configparser',
-               'repr': 'reprlib',
-               'FileDialog': 'tkinter.filedialog',
-               'FixTk': 'tkinter._fix',
-               'ScrolledText': 'tkinter.scrolledtext',
-               'SimpleDialog': 'tkinter.simpledialog',
-               'Tix': 'tkinter.tix',
-               'tkColorChooser': 'tkinter.colorchooser',
-               'tkCommonDialog': 'tkinter.commondialog',
-               'Tkconstants': 'tkinter.constants',
-               'Tkdnd': 'tkinter.dnd',
-               'tkFileDialog': 'tkinter.filedialog',
-               'tkFont': 'tkinter.font',
-               'Tkinter': 'tkinter',
-               'tkMessageBox': 'tkinter.messagebox',
-               'tkSimpleDialog': 'tkinter.simpledialog',
-               'turtle': 'tkinter.turtle'
-               }
+               'repr': 'reprlib'}
 
     def check_rename(self, module_name, new_module_name):
         """Make sure that:
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
index 6b41a17..fa170ef 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -3,7 +3,7 @@
 import unittest
 import os
 from test import test_support
-from tkinter import Tcl
+from Tkinter import Tcl
 from _tkinter import TclError
 
 class TclTest(unittest.TestCase):
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
deleted file mode 100644
index 554cf86..0000000
--- a/Lib/tkinter/__init__.py
+++ /dev/null
@@ -1,3756 +0,0 @@
-"""Wrapper functions for Tcl/Tk.
-
-Tkinter provides classes which allow the display, positioning and
-control of widgets. Toplevel widgets are Tk and Toplevel. Other
-widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton,
-Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox
-LabelFrame and PanedWindow.
-
-Properties of the widgets are specified with keyword arguments.
-Keyword arguments have the same name as the corresponding resource
-under Tk.
-
-Widgets are positioned with one of the geometry managers Place, Pack
-or Grid. These managers can be called with methods place, pack, grid
-available in every Widget.
-
-Actions are bound to events by resources (e.g. keyword argument
-command) or with the method bind.
-
-Example (Hello, World):
-import tkinter
-from tkinter.constants import *
-tk = tkinter.Tk()
-frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
-frame.pack(fill=BOTH,expand=1)
-label = tkinter.Label(frame, text="Hello, World")
-label.pack(fill=X, expand=1)
-button = tkinter.Button(frame,text="Exit",command=tk.destroy)
-button.pack(side=BOTTOM)
-tk.mainloop()
-"""
-
-__version__ = "$Revision$"
-
-import sys
-if sys.platform == "win32":
-    # Attempt to configure Tcl/Tk without requiring PATH
-    from tkinter import _fix
-import _tkinter # If this fails your Python may not be configured for Tk
-TclError = _tkinter.TclError
-from types import *
-from tkinter.constants import *
-try:
-    import MacOS; _MacOS = MacOS; del MacOS
-except ImportError:
-    _MacOS = None
-
-wantobjects = 1
-
-TkVersion = float(_tkinter.TK_VERSION)
-TclVersion = float(_tkinter.TCL_VERSION)
-
-READABLE = _tkinter.READABLE
-WRITABLE = _tkinter.WRITABLE
-EXCEPTION = _tkinter.EXCEPTION
-
-# These are not always defined, e.g. not on Win32 with Tk 8.0 :-(
-try: _tkinter.createfilehandler
-except AttributeError: _tkinter.createfilehandler = None
-try: _tkinter.deletefilehandler
-except AttributeError: _tkinter.deletefilehandler = None
-
-
-def _flatten(tuple):
-    """Internal function."""
-    res = ()
-    for item in tuple:
-        if type(item) in (TupleType, ListType):
-            res = res + _flatten(item)
-        elif item is not None:
-            res = res + (item,)
-    return res
-
-try: _flatten = _tkinter._flatten
-except AttributeError: pass
-
-def _cnfmerge(cnfs):
-    """Internal function."""
-    if type(cnfs) is DictionaryType:
-        return cnfs
-    elif type(cnfs) in (NoneType, StringType):
-        return cnfs
-    else:
-        cnf = {}
-        for c in _flatten(cnfs):
-            try:
-                cnf.update(c)
-            except (AttributeError, TypeError), msg:
-                print "_cnfmerge: fallback due to:", msg
-                for k, v in c.items():
-                    cnf[k] = v
-        return cnf
-
-try: _cnfmerge = _tkinter._cnfmerge
-except AttributeError: pass
-
-class Event:
-    """Container for the properties of an event.
-
-    Instances of this type are generated if one of the following events occurs:
-
-    KeyPress, KeyRelease - for keyboard events
-    ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events
-    Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,
-    Colormap, Gravity, Reparent, Property, Destroy, Activate,
-    Deactivate - for window events.
-
-    If a callback function for one of these events is registered
-    using bind, bind_all, bind_class, or tag_bind, the callback is
-    called with an Event as first argument. It will have the
-    following attributes (in braces are the event types for which
-    the attribute is valid):
-
-        serial - serial number of event
-    num - mouse button pressed (ButtonPress, ButtonRelease)
-    focus - whether the window has the focus (Enter, Leave)
-    height - height of the exposed window (Configure, Expose)
-    width - width of the exposed window (Configure, Expose)
-    keycode - keycode of the pressed key (KeyPress, KeyRelease)
-    state - state of the event as a number (ButtonPress, ButtonRelease,
-                            Enter, KeyPress, KeyRelease,
-                            Leave, Motion)
-    state - state as a string (Visibility)
-    time - when the event occurred
-    x - x-position of the mouse
-    y - y-position of the mouse
-    x_root - x-position of the mouse on the screen
-             (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
-    y_root - y-position of the mouse on the screen
-             (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
-    char - pressed character (KeyPress, KeyRelease)
-    send_event - see X/Windows documentation
-    keysym - keysym of the event as a string (KeyPress, KeyRelease)
-    keysym_num - keysym of the event as a number (KeyPress, KeyRelease)
-    type - type of the event as a number
-    widget - widget in which the event occurred
-    delta - delta of wheel movement (MouseWheel)
-    """
-    pass
-
-_support_default_root = 1
-_default_root = None
-
-def NoDefaultRoot():
-    """Inhibit setting of default root window.
-
-    Call this function to inhibit that the first instance of
-    Tk is used for windows without an explicit parent window.
-    """
-    global _support_default_root
-    _support_default_root = 0
-    global _default_root
-    _default_root = None
-    del _default_root
-
-def _tkerror(err):
-    """Internal function."""
-    pass
-
-def _exit(code='0'):
-    """Internal function. Calling it will throw the exception SystemExit."""
-    raise SystemExit, code
-
-_varnum = 0
-class Variable:
-    """Class to define value holders for e.g. buttons.
-
-    Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations
-    that constrain the type of the value returned from get()."""
-    _default = ""
-    def __init__(self, master=None, value=None, name=None):
-        """Construct a variable
-
-        MASTER can be given as master widget.
-        VALUE is an optional value (defaults to "")
-        NAME is an optional Tcl name (defaults to PY_VARnum).
-
-        If NAME matches an existing variable and VALUE is omitted
-        then the existing value is retained.
-        """
-        global _varnum
-        if not master:
-            master = _default_root
-        self._master = master
-        self._tk = master.tk
-        if name:
-            self._name = name
-        else:
-            self._name = 'PY_VAR' + repr(_varnum)
-            _varnum += 1
-        if value is not None:
-            self.set(value)
-        elif not self._tk.call("info", "exists", self._name):
-            self.set(self._default)
-    def __del__(self):
-        """Unset the variable in Tcl."""
-        self._tk.globalunsetvar(self._name)
-    def __str__(self):
-        """Return the name of the variable in Tcl."""
-        return self._name
-    def set(self, value):
-        """Set the variable to VALUE."""
-        return self._tk.globalsetvar(self._name, value)
-    def get(self):
-        """Return value of variable."""
-        return self._tk.globalgetvar(self._name)
-    def trace_variable(self, mode, callback):
-        """Define a trace callback for the variable.
-
-        MODE is one of "r", "w", "u" for read, write, undefine.
-        CALLBACK must be a function which is called when
-        the variable is read, written or undefined.
-
-        Return the name of the callback.
-        """
-        cbname = self._master._register(callback)
-        self._tk.call("trace", "variable", self._name, mode, cbname)
-        return cbname
-    trace = trace_variable
-    def trace_vdelete(self, mode, cbname):
-        """Delete the trace callback for a variable.
-
-        MODE is one of "r", "w", "u" for read, write, undefine.
-        CBNAME is the name of the callback returned from trace_variable or trace.
-        """
-        self._tk.call("trace", "vdelete", self._name, mode, cbname)
-        self._master.deletecommand(cbname)
-    def trace_vinfo(self):
-        """Return all trace callback information."""
-        return map(self._tk.split, self._tk.splitlist(
-            self._tk.call("trace", "vinfo", self._name)))
-    def __eq__(self, other):
-        """Comparison for equality (==).
-
-        Note: if the Variable's master matters to behavior
-        also compare self._master == other._master
-        """
-        return self.__class__.__name__ == other.__class__.__name__ \
-            and self._name == other._name
-
-class StringVar(Variable):
-    """Value holder for strings variables."""
-    _default = ""
-    def __init__(self, master=None, value=None, name=None):
-        """Construct a string variable.
-
-        MASTER can be given as master widget.
-        VALUE is an optional value (defaults to "")
-        NAME is an optional Tcl name (defaults to PY_VARnum).
-
-        If NAME matches an existing variable and VALUE is omitted
-        then the existing value is retained.
-        """
-        Variable.__init__(self, master, value, name)
-
-    def get(self):
-        """Return value of variable as string."""
-        value = self._tk.globalgetvar(self._name)
-        if isinstance(value, basestring):
-            return value
-        return str(value)
-
-class IntVar(Variable):
-    """Value holder for integer variables."""
-    _default = 0
-    def __init__(self, master=None, value=None, name=None):
-        """Construct an integer variable.
-
-        MASTER can be given as master widget.
-        VALUE is an optional value (defaults to 0)
-        NAME is an optional Tcl name (defaults to PY_VARnum).
-
-        If NAME matches an existing variable and VALUE is omitted
-        then the existing value is retained.
-        """
-        Variable.__init__(self, master, value, name)
-
-    def set(self, value):
-        """Set the variable to value, converting booleans to integers."""
-        if isinstance(value, bool):
-            value = int(value)
-        return Variable.set(self, value)
-
-    def get(self):
-        """Return the value of the variable as an integer."""
-        return getint(self._tk.globalgetvar(self._name))
-
-class DoubleVar(Variable):
-    """Value holder for float variables."""
-    _default = 0.0
-    def __init__(self, master=None, value=None, name=None):
-        """Construct a float variable.
-
-        MASTER can be given as master widget.
-        VALUE is an optional value (defaults to 0.0)
-        NAME is an optional Tcl name (defaults to PY_VARnum).
-
-        If NAME matches an existing variable and VALUE is omitted
-        then the existing value is retained.
-        """
-        Variable.__init__(self, master, value, name)
-
-    def get(self):
-        """Return the value of the variable as a float."""
-        return getdouble(self._tk.globalgetvar(self._name))
-
-class BooleanVar(Variable):
-    """Value holder for boolean variables."""
-    _default = False
-    def __init__(self, master=None, value=None, name=None):
-        """Construct a boolean variable.
-
-        MASTER can be given as master widget.
-        VALUE is an optional value (defaults to False)
-        NAME is an optional Tcl name (defaults to PY_VARnum).
-
-        If NAME matches an existing variable and VALUE is omitted
-        then the existing value is retained.
-        """
-        Variable.__init__(self, master, value, name)
-
-    def get(self):
-        """Return the value of the variable as a bool."""
-        return self._tk.getboolean(self._tk.globalgetvar(self._name))
-
-def mainloop(n=0):
-    """Run the main loop of Tcl."""
-    _default_root.tk.mainloop(n)
-
-getint = int
-
-getdouble = float
-
-def getboolean(s):
-    """Convert true and false to integer values 1 and 0."""
-    return _default_root.tk.getboolean(s)
-
-# Methods defined on both toplevel and interior widgets
-class Misc:
-    """Internal class.
-
-    Base class which defines methods common for interior widgets."""
-
-    # XXX font command?
-    _tclCommands = None
-    def destroy(self):
-        """Internal function.
-
-        Delete all Tcl commands created for
-        this widget in the Tcl interpreter."""
-        if self._tclCommands is not None:
-            for name in self._tclCommands:
-                #print '- Tkinter: deleted command', name
-                self.tk.deletecommand(name)
-            self._tclCommands = None
-    def deletecommand(self, name):
-        """Internal function.
-
-        Delete the Tcl command provided in NAME."""
-        #print '- Tkinter: deleted command', name
-        self.tk.deletecommand(name)
-        try:
-            self._tclCommands.remove(name)
-        except ValueError:
-            pass
-    def tk_strictMotif(self, boolean=None):
-        """Set Tcl internal variable, whether the look and feel
-        should adhere to Motif.
-
-        A parameter of 1 means adhere to Motif (e.g. no color
-        change if mouse passes over slider).
-        Returns the set value."""
-        return self.tk.getboolean(self.tk.call(
-            'set', 'tk_strictMotif', boolean))
-    def tk_bisque(self):
-        """Change the color scheme to light brown as used in Tk 3.6 and before."""
-        self.tk.call('tk_bisque')
-    def tk_setPalette(self, *args, **kw):
-        """Set a new color scheme for all widget elements.
-
-        A single color as argument will cause that all colors of Tk
-        widget elements are derived from this.
-        Alternatively several keyword parameters and its associated
-        colors can be given. The following keywords are valid:
-        activeBackground, foreground, selectColor,
-        activeForeground, highlightBackground, selectBackground,
-        background, highlightColor, selectForeground,
-        disabledForeground, insertBackground, troughColor."""
-        self.tk.call(('tk_setPalette',)
-              + _flatten(args) + _flatten(kw.items()))
-    def tk_menuBar(self, *args):
-        """Do not use. Needed in Tk 3.6 and earlier."""
-        pass # obsolete since Tk 4.0
-    def wait_variable(self, name='PY_VAR'):
-        """Wait until the variable is modified.
-
-        A parameter of type IntVar, StringVar, DoubleVar or
-        BooleanVar must be given."""
-        self.tk.call('tkwait', 'variable', name)
-    waitvar = wait_variable # XXX b/w compat
-    def wait_window(self, window=None):
-        """Wait until a WIDGET is destroyed.
-
-        If no parameter is given self is used."""
-        if window is None:
-            window = self
-        self.tk.call('tkwait', 'window', window._w)
-    def wait_visibility(self, window=None):
-        """Wait until the visibility of a WIDGET changes
-        (e.g. it appears).
-
-        If no parameter is given self is used."""
-        if window is None:
-            window = self
-        self.tk.call('tkwait', 'visibility', window._w)
-    def setvar(self, name='PY_VAR', value='1'):
-        """Set Tcl variable NAME to VALUE."""
-        self.tk.setvar(name, value)
-    def getvar(self, name='PY_VAR'):
-        """Return value of Tcl variable NAME."""
-        return self.tk.getvar(name)
-    getint = int
-    getdouble = float
-    def getboolean(self, s):
-        """Return a boolean value for Tcl boolean values true and false given as parameter."""
-        return self.tk.getboolean(s)
-    def focus_set(self):
-        """Direct input focus to this widget.
-
-        If the application currently does not have the focus
-        this widget will get the focus if the application gets
-        the focus through the window manager."""
-        self.tk.call('focus', self._w)
-    focus = focus_set # XXX b/w compat?
-    def focus_force(self):
-        """Direct input focus to this widget even if the
-        application does not have the focus. Use with
-        caution!"""
-        self.tk.call('focus', '-force', self._w)
-    def focus_get(self):
-        """Return the widget which has currently the focus in the
-        application.
-
-        Use focus_displayof to allow working with several
-        displays. Return None if application does not have
-        the focus."""
-        name = self.tk.call('focus')
-        if name == 'none' or not name: return None
-        return self._nametowidget(name)
-    def focus_displayof(self):
-        """Return the widget which has currently the focus on the
-        display where this widget is located.
-
-        Return None if the application does not have the focus."""
-        name = self.tk.call('focus', '-displayof', self._w)
-        if name == 'none' or not name: return None
-        return self._nametowidget(name)
-    def focus_lastfor(self):
-        """Return the widget which would have the focus if top level
-        for this widget gets the focus from the window manager."""
-        name = self.tk.call('focus', '-lastfor', self._w)
-        if name == 'none' or not name: return None
-        return self._nametowidget(name)
-    def tk_focusFollowsMouse(self):
-        """The widget under mouse will get automatically focus. Can not
-        be disabled easily."""
-        self.tk.call('tk_focusFollowsMouse')
-    def tk_focusNext(self):
-        """Return the next widget in the focus order which follows
-        widget which has currently the focus.
-
-        The focus order first goes to the next child, then to
-        the children of the child recursively and then to the
-        next sibling which is higher in the stacking order.  A
-        widget is omitted if it has the takefocus resource set
-        to 0."""
-        name = self.tk.call('tk_focusNext', self._w)
-        if not name: return None
-        return self._nametowidget(name)
-    def tk_focusPrev(self):
-        """Return previous widget in the focus order. See tk_focusNext for details."""
-        name = self.tk.call('tk_focusPrev', self._w)
-        if not name: return None
-        return self._nametowidget(name)
-    def after(self, ms, func=None, *args):
-        """Call function once after given time.
-
-        MS specifies the time in milliseconds. FUNC gives the
-        function which shall be called. Additional parameters
-        are given as parameters to the function call.  Return
-        identifier to cancel scheduling with after_cancel."""
-        if not func:
-            # I'd rather use time.sleep(ms*0.001)
-            self.tk.call('after', ms)
-        else:
-            def callit():
-                try:
-                    func(*args)
-                finally:
-                    try:
-                        self.deletecommand(name)
-                    except TclError:
-                        pass
-            name = self._register(callit)
-            return self.tk.call('after', ms, name)
-    def after_idle(self, func, *args):
-        """Call FUNC once if the Tcl main loop has no event to
-        process.
-
-        Return an identifier to cancel the scheduling with
-        after_cancel."""
-        return self.after('idle', func, *args)
-    def after_cancel(self, id):
-        """Cancel scheduling of function identified with ID.
-
-        Identifier returned by after or after_idle must be
-        given as first parameter."""
-        try:
-            data = self.tk.call('after', 'info', id)
-            # In Tk 8.3, splitlist returns: (script, type)
-            # In Tk 8.4, splitlist may return (script, type) or (script,)
-            script = self.tk.splitlist(data)[0]
-            self.deletecommand(script)
-        except TclError:
-            pass
-        self.tk.call('after', 'cancel', id)
-    def bell(self, displayof=0):
-        """Ring a display's bell."""
-        self.tk.call(('bell',) + self._displayof(displayof))
-
-    # Clipboard handling:
-    def clipboard_get(self, **kw):
-        """Retrieve data from the clipboard on window's display.
-
-        The window keyword defaults to the root window of the Tkinter
-        application.
-
-        The type keyword specifies the form in which the data is
-        to be returned and should be an atom name such as STRING
-        or FILE_NAME.  Type defaults to STRING.
-
-        This command is equivalent to:
-
-        selection_get(CLIPBOARD)
-        """
-        return self.tk.call(('clipboard', 'get') + self._options(kw))
-
-    def clipboard_clear(self, **kw):
-        """Clear the data in the Tk clipboard.
-
-        A widget specified for the optional displayof keyword
-        argument specifies the target display."""
-        if not kw.has_key('displayof'): kw['displayof'] = self._w
-        self.tk.call(('clipboard', 'clear') + self._options(kw))
-    def clipboard_append(self, string, **kw):
-        """Append STRING to the Tk clipboard.
-
-        A widget specified at the optional displayof keyword
-        argument specifies the target display. The clipboard
-        can be retrieved with selection_get."""
-        if not kw.has_key('displayof'): kw['displayof'] = self._w
-        self.tk.call(('clipboard', 'append') + self._options(kw)
-              + ('--', string))
-    # XXX grab current w/o window argument
-    def grab_current(self):
-        """Return widget which has currently the grab in this application
-        or None."""
-        name = self.tk.call('grab', 'current', self._w)
-        if not name: return None
-        return self._nametowidget(name)
-    def grab_release(self):
-        """Release grab for this widget if currently set."""
-        self.tk.call('grab', 'release', self._w)
-    def grab_set(self):
-        """Set grab for this widget.
-
-        A grab directs all events to this and descendant
-        widgets in the application."""
-        self.tk.call('grab', 'set', self._w)
-    def grab_set_global(self):
-        """Set global grab for this widget.
-
-        A global grab directs all events to this and
-        descendant widgets on the display. Use with caution -
-        other applications do not get events anymore."""
-        self.tk.call('grab', 'set', '-global', self._w)
-    def grab_status(self):
-        """Return None, "local" or "global" if this widget has
-        no, a local or a global grab."""
-        status = self.tk.call('grab', 'status', self._w)
-        if status == 'none': status = None
-        return status
-    def option_add(self, pattern, value, priority = None):
-        """Set a VALUE (second parameter) for an option
-        PATTERN (first parameter).
-
-        An optional third parameter gives the numeric priority
-        (defaults to 80)."""
-        self.tk.call('option', 'add', pattern, value, priority)
-    def option_clear(self):
-        """Clear the option database.
-
-        It will be reloaded if option_add is called."""
-        self.tk.call('option', 'clear')
-    def option_get(self, name, className):
-        """Return the value for an option NAME for this widget
-        with CLASSNAME.
-
-        Values with higher priority override lower values."""
-        return self.tk.call('option', 'get', self._w, name, className)
-    def option_readfile(self, fileName, priority = None):
-        """Read file FILENAME into the option database.
-
-        An optional second parameter gives the numeric
-        priority."""
-        self.tk.call('option', 'readfile', fileName, priority)
-    def selection_clear(self, **kw):
-        """Clear the current X selection."""
-        if not kw.has_key('displayof'): kw['displayof'] = self._w
-        self.tk.call(('selection', 'clear') + self._options(kw))
-    def selection_get(self, **kw):
-        """Return the contents of the current X selection.
-
-        A keyword parameter selection specifies the name of
-        the selection and defaults to PRIMARY.  A keyword
-        parameter displayof specifies a widget on the display
-        to use."""
-        if not kw.has_key('displayof'): kw['displayof'] = self._w
-        return self.tk.call(('selection', 'get') + self._options(kw))
-    def selection_handle(self, command, **kw):
-        """Specify a function COMMAND to call if the X
-        selection owned by this widget is queried by another
-        application.
-
-        This function must return the contents of the
-        selection. The function will be called with the
-        arguments OFFSET and LENGTH which allows the chunking
-        of very long selections. The following keyword
-        parameters can be provided:
-        selection - name of the selection (default PRIMARY),
-        type - type of the selection (e.g. STRING, FILE_NAME)."""
-        name = self._register(command)
-        self.tk.call(('selection', 'handle') + self._options(kw)
-              + (self._w, name))
-    def selection_own(self, **kw):
-        """Become owner of X selection.
-
-        A keyword parameter selection specifies the name of
-        the selection (default PRIMARY)."""
-        self.tk.call(('selection', 'own') +
-                 self._options(kw) + (self._w,))
-    def selection_own_get(self, **kw):
-        """Return owner of X selection.
-
-        The following keyword parameter can
-        be provided:
-        selection - name of the selection (default PRIMARY),
-        type - type of the selection (e.g. STRING, FILE_NAME)."""
-        if not kw.has_key('displayof'): kw['displayof'] = self._w
-        name = self.tk.call(('selection', 'own') + self._options(kw))
-        if not name: return None
-        return self._nametowidget(name)
-    def send(self, interp, cmd, *args):
-        """Send Tcl command CMD to different interpreter INTERP to be executed."""
-        return self.tk.call(('send', interp, cmd) + args)
-    def lower(self, belowThis=None):
-        """Lower this widget in the stacking order."""
-        self.tk.call('lower', self._w, belowThis)
-    def tkraise(self, aboveThis=None):
-        """Raise this widget in the stacking order."""
-        self.tk.call('raise', self._w, aboveThis)
-    lift = tkraise
-    def colormodel(self, value=None):
-        """Useless. Not implemented in Tk."""
-        return self.tk.call('tk', 'colormodel', self._w, value)
-    def winfo_atom(self, name, displayof=0):
-        """Return integer which represents atom NAME."""
-        args = ('winfo', 'atom') + self._displayof(displayof) + (name,)
-        return getint(self.tk.call(args))
-    def winfo_atomname(self, id, displayof=0):
-        """Return name of atom with identifier ID."""
-        args = ('winfo', 'atomname') \
-               + self._displayof(displayof) + (id,)
-        return self.tk.call(args)
-    def winfo_cells(self):
-        """Return number of cells in the colormap for this widget."""
-        return getint(
-            self.tk.call('winfo', 'cells', self._w))
-    def winfo_children(self):
-        """Return a list of all widgets which are children of this widget."""
-        result = []
-        for child in self.tk.splitlist(
-            self.tk.call('winfo', 'children', self._w)):
-            try:
-                # Tcl sometimes returns extra windows, e.g. for
-                # menus; those need to be skipped
-                result.append(self._nametowidget(child))
-            except KeyError:
-                pass
-        return result
-
-    def winfo_class(self):
-        """Return window class name of this widget."""
-        return self.tk.call('winfo', 'class', self._w)
-    def winfo_colormapfull(self):
-        """Return true if at the last color request the colormap was full."""
-        return self.tk.getboolean(
-            self.tk.call('winfo', 'colormapfull', self._w))
-    def winfo_containing(self, rootX, rootY, displayof=0):
-        """Return the widget which is at the root coordinates ROOTX, ROOTY."""
-        args = ('winfo', 'containing') \
-               + self._displayof(displayof) + (rootX, rootY)
-        name = self.tk.call(args)
-        if not name: return None
-        return self._nametowidget(name)
-    def winfo_depth(self):
-        """Return the number of bits per pixel."""
-        return getint(self.tk.call('winfo', 'depth', self._w))
-    def winfo_exists(self):
-        """Return true if this widget exists."""
-        return getint(
-            self.tk.call('winfo', 'exists', self._w))
-    def winfo_fpixels(self, number):
-        """Return the number of pixels for the given distance NUMBER
-        (e.g. "3c") as float."""
-        return getdouble(self.tk.call(
-            'winfo', 'fpixels', self._w, number))
-    def winfo_geometry(self):
-        """Return geometry string for this widget in the form "widthxheight+X+Y"."""
-        return self.tk.call('winfo', 'geometry', self._w)
-    def winfo_height(self):
-        """Return height of this widget."""
-        return getint(
-            self.tk.call('winfo', 'height', self._w))
-    def winfo_id(self):
-        """Return identifier ID for this widget."""
-        return self.tk.getint(
-            self.tk.call('winfo', 'id', self._w))
-    def winfo_interps(self, displayof=0):
-        """Return the name of all Tcl interpreters for this display."""
-        args = ('winfo', 'interps') + self._displayof(displayof)
-        return self.tk.splitlist(self.tk.call(args))
-    def winfo_ismapped(self):
-        """Return true if this widget is mapped."""
-        return getint(
-            self.tk.call('winfo', 'ismapped', self._w))
-    def winfo_manager(self):
-        """Return the window mananger name for this widget."""
-        return self.tk.call('winfo', 'manager', self._w)
-    def winfo_name(self):
-        """Return the name of this widget."""
-        return self.tk.call('winfo', 'name', self._w)
-    def winfo_parent(self):
-        """Return the name of the parent of this widget."""
-        return self.tk.call('winfo', 'parent', self._w)
-    def winfo_pathname(self, id, displayof=0):
-        """Return the pathname of the widget given by ID."""
-        args = ('winfo', 'pathname') \
-               + self._displayof(displayof) + (id,)
-        return self.tk.call(args)
-    def winfo_pixels(self, number):
-        """Rounded integer value of winfo_fpixels."""
-        return getint(
-            self.tk.call('winfo', 'pixels', self._w, number))
-    def winfo_pointerx(self):
-        """Return the x coordinate of the pointer on the root window."""
-        return getint(
-            self.tk.call('winfo', 'pointerx', self._w))
-    def winfo_pointerxy(self):
-        """Return a tuple of x and y coordinates of the pointer on the root window."""
-        return self._getints(
-            self.tk.call('winfo', 'pointerxy', self._w))
-    def winfo_pointery(self):
-        """Return the y coordinate of the pointer on the root window."""
-        return getint(
-            self.tk.call('winfo', 'pointery', self._w))
-    def winfo_reqheight(self):
-        """Return requested height of this widget."""
-        return getint(
-            self.tk.call('winfo', 'reqheight', self._w))
-    def winfo_reqwidth(self):
-        """Return requested width of this widget."""
-        return getint(
-            self.tk.call('winfo', 'reqwidth', self._w))
-    def winfo_rgb(self, color):
-        """Return tuple of decimal values for red, green, blue for
-        COLOR in this widget."""
-        return self._getints(
-            self.tk.call('winfo', 'rgb', self._w, color))
-    def winfo_rootx(self):
-        """Return x coordinate of upper left corner of this widget on the
-        root window."""
-        return getint(
-            self.tk.call('winfo', 'rootx', self._w))
-    def winfo_rooty(self):
-        """Return y coordinate of upper left corner of this widget on the
-        root window."""
-        return getint(
-            self.tk.call('winfo', 'rooty', self._w))
-    def winfo_screen(self):
-        """Return the screen name of this widget."""
-        return self.tk.call('winfo', 'screen', self._w)
-    def winfo_screencells(self):
-        """Return the number of the cells in the colormap of the screen
-        of this widget."""
-        return getint(
-            self.tk.call('winfo', 'screencells', self._w))
-    def winfo_screendepth(self):
-        """Return the number of bits per pixel of the root window of the
-        screen of this widget."""
-        return getint(
-            self.tk.call('winfo', 'screendepth', self._w))
-    def winfo_screenheight(self):
-        """Return the number of pixels of the height of the screen of this widget
-        in pixel."""
-        return getint(
-            self.tk.call('winfo', 'screenheight', self._w))
-    def winfo_screenmmheight(self):
-        """Return the number of pixels of the height of the screen of
-        this widget in mm."""
-        return getint(
-            self.tk.call('winfo', 'screenmmheight', self._w))
-    def winfo_screenmmwidth(self):
-        """Return the number of pixels of the width of the screen of
-        this widget in mm."""
-        return getint(
-            self.tk.call('winfo', 'screenmmwidth', self._w))
-    def winfo_screenvisual(self):
-        """Return one of the strings directcolor, grayscale, pseudocolor,
-        staticcolor, staticgray, or truecolor for the default
-        colormodel of this screen."""
-        return self.tk.call('winfo', 'screenvisual', self._w)
-    def winfo_screenwidth(self):
-        """Return the number of pixels of the width of the screen of
-        this widget in pixel."""
-        return getint(
-            self.tk.call('winfo', 'screenwidth', self._w))
-    def winfo_server(self):
-        """Return information of the X-Server of the screen of this widget in
-        the form "XmajorRminor vendor vendorVersion"."""
-        return self.tk.call('winfo', 'server', self._w)
-    def winfo_toplevel(self):
-        """Return the toplevel widget of this widget."""
-        return self._nametowidget(self.tk.call(
-            'winfo', 'toplevel', self._w))
-    def winfo_viewable(self):
-        """Return true if the widget and all its higher ancestors are mapped."""
-        return getint(
-            self.tk.call('winfo', 'viewable', self._w))
-    def winfo_visual(self):
-        """Return one of the strings directcolor, grayscale, pseudocolor,
-        staticcolor, staticgray, or truecolor for the
-        colormodel of this widget."""
-        return self.tk.call('winfo', 'visual', self._w)
-    def winfo_visualid(self):
-        """Return the X identifier for the visual for this widget."""
-        return self.tk.call('winfo', 'visualid', self._w)
-    def winfo_visualsavailable(self, includeids=0):
-        """Return a list of all visuals available for the screen
-        of this widget.
-
-        Each item in the list consists of a visual name (see winfo_visual), a
-        depth and if INCLUDEIDS=1 is given also the X identifier."""
-        data = self.tk.split(
-            self.tk.call('winfo', 'visualsavailable', self._w,
-                     includeids and 'includeids' or None))
-        if type(data) is StringType:
-            data = [self.tk.split(data)]
-        return map(self.__winfo_parseitem, data)
-    def __winfo_parseitem(self, t):
-        """Internal function."""
-        return t[:1] + tuple(map(self.__winfo_getint, t[1:]))
-    def __winfo_getint(self, x):
-        """Internal function."""
-        return int(x, 0)
-    def winfo_vrootheight(self):
-        """Return the height of the virtual root window associated with this
-        widget in pixels. If there is no virtual root window return the
-        height of the screen."""
-        return getint(
-            self.tk.call('winfo', 'vrootheight', self._w))
-    def winfo_vrootwidth(self):
-        """Return the width of the virtual root window associated with this
-        widget in pixel. If there is no virtual root window return the
-        width of the screen."""
-        return getint(
-            self.tk.call('winfo', 'vrootwidth', self._w))
-    def winfo_vrootx(self):
-        """Return the x offset of the virtual root relative to the root
-        window of the screen of this widget."""
-        return getint(
-            self.tk.call('winfo', 'vrootx', self._w))
-    def winfo_vrooty(self):
-        """Return the y offset of the virtual root relative to the root
-        window of the screen of this widget."""
-        return getint(
-            self.tk.call('winfo', 'vrooty', self._w))
-    def winfo_width(self):
-        """Return the width of this widget."""
-        return getint(
-            self.tk.call('winfo', 'width', self._w))
-    def winfo_x(self):
-        """Return the x coordinate of the upper left corner of this widget
-        in the parent."""
-        return getint(
-            self.tk.call('winfo', 'x', self._w))
-    def winfo_y(self):
-        """Return the y coordinate of the upper left corner of this widget
-        in the parent."""
-        return getint(
-            self.tk.call('winfo', 'y', self._w))
-    def update(self):
-        """Enter event loop until all pending events have been processed by Tcl."""
-        self.tk.call('update')
-    def update_idletasks(self):
-        """Enter event loop until all idle callbacks have been called. This
-        will update the display of windows but not process events caused by
-        the user."""
-        self.tk.call('update', 'idletasks')
-    def bindtags(self, tagList=None):
-        """Set or get the list of bindtags for this widget.
-
-        With no argument return the list of all bindtags associated with
-        this widget. With a list of strings as argument the bindtags are
-        set to this list. The bindtags determine in which order events are
-        processed (see bind)."""
-        if tagList is None:
-            return self.tk.splitlist(
-                self.tk.call('bindtags', self._w))
-        else:
-            self.tk.call('bindtags', self._w, tagList)
-    def _bind(self, what, sequence, func, add, needcleanup=1):
-        """Internal function."""
-        if type(func) is StringType:
-            self.tk.call(what + (sequence, func))
-        elif func:
-            funcid = self._register(func, self._substitute,
-                        needcleanup)
-            cmd = ('%sif {"[%s %s]" == "break"} break\n'
-                   %
-                   (add and '+' or '',
-                funcid, self._subst_format_str))
-            self.tk.call(what + (sequence, cmd))
-            return funcid
-        elif sequence:
-            return self.tk.call(what + (sequence,))
-        else:
-            return self.tk.splitlist(self.tk.call(what))
-    def bind(self, sequence=None, func=None, add=None):
-        """Bind to this widget at event SEQUENCE a call to function FUNC.
-
-        SEQUENCE is a string of concatenated event
-        patterns. An event pattern is of the form
-        <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
-        of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
-        Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
-        B3, Alt, Button4, B4, Double, Button5, B5 Triple,
-        Mod1, M1. TYPE is one of Activate, Enter, Map,
-        ButtonPress, Button, Expose, Motion, ButtonRelease
-        FocusIn, MouseWheel, Circulate, FocusOut, Property,
-        Colormap, Gravity Reparent, Configure, KeyPress, Key,
-        Unmap, Deactivate, KeyRelease Visibility, Destroy,
-        Leave and DETAIL is the button number for ButtonPress,
-        ButtonRelease and DETAIL is the Keysym for KeyPress and
-        KeyRelease. Examples are
-        <Control-Button-1> for pressing Control and mouse button 1 or
-        <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
-        An event pattern can also be a virtual event of the form
-        <<AString>> where AString can be arbitrary. This
-        event can be generated by event_generate.
-        If events are concatenated they must appear shortly
-        after each other.
-
-        FUNC will be called if the event sequence occurs with an
-        instance of Event as argument. If the return value of FUNC is
-        "break" no further bound function is invoked.
-
-        An additional boolean parameter ADD specifies whether FUNC will
-        be called additionally to the other bound function or whether
-        it will replace the previous function.
-
-        Bind will return an identifier to allow deletion of the bound function with
-        unbind without memory leak.
-
-        If FUNC or SEQUENCE is omitted the bound function or list
-        of bound events are returned."""
-
-        return self._bind(('bind', self._w), sequence, func, add)
-    def unbind(self, sequence, funcid=None):
-        """Unbind for this widget for event SEQUENCE  the
-        function identified with FUNCID."""
-        self.tk.call('bind', self._w, sequence, '')
-        if funcid:
-            self.deletecommand(funcid)
-    def bind_all(self, sequence=None, func=None, add=None):
-        """Bind to all widgets at an event SEQUENCE a call to function FUNC.
-        An additional boolean parameter ADD specifies whether FUNC will
-        be called additionally to the other bound function or whether
-        it will replace the previous function. See bind for the return value."""
-        return self._bind(('bind', 'all'), sequence, func, add, 0)
-    def unbind_all(self, sequence):
-        """Unbind for all widgets for event SEQUENCE all functions."""
-        self.tk.call('bind', 'all' , sequence, '')
-    def bind_class(self, className, sequence=None, func=None, add=None):
-
-        """Bind to widgets with bindtag CLASSNAME at event
-        SEQUENCE a call of function FUNC. An additional
-        boolean parameter ADD specifies whether FUNC will be
-        called additionally to the other bound function or
-        whether it will replace the previous function. See bind for
-        the return value."""
-
-        return self._bind(('bind', className), sequence, func, add, 0)
-    def unbind_class(self, className, sequence):
-        """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE
-        all functions."""
-        self.tk.call('bind', className , sequence, '')
-    def mainloop(self, n=0):
-        """Call the mainloop of Tk."""
-        self.tk.mainloop(n)
-    def quit(self):
-        """Quit the Tcl interpreter. All widgets will be destroyed."""
-        self.tk.quit()
-    def _getints(self, string):
-        """Internal function."""
-        if string:
-            return tuple(map(getint, self.tk.splitlist(string)))
-    def _getdoubles(self, string):
-        """Internal function."""
-        if string:
-            return tuple(map(getdouble, self.tk.splitlist(string)))
-    def _getboolean(self, string):
-        """Internal function."""
-        if string:
-            return self.tk.getboolean(string)
-    def _displayof(self, displayof):
-        """Internal function."""
-        if displayof:
-            return ('-displayof', displayof)
-        if displayof is None:
-            return ('-displayof', self._w)
-        return ()
-    def _options(self, cnf, kw = None):
-        """Internal function."""
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        else:
-            cnf = _cnfmerge(cnf)
-        res = ()
-        for k, v in cnf.items():
-            if v is not None:
-                if k[-1] == '_': k = k[:-1]
-                if callable(v):
-                    v = self._register(v)
-                res = res + ('-'+k, v)
-        return res
-    def nametowidget(self, name):
-        """Return the Tkinter instance of a widget identified by
-        its Tcl name NAME."""
-        w = self
-        if name[0] == '.':
-            w = w._root()
-            name = name[1:]
-        while name:
-            i = name.find('.')
-            if i >= 0:
-                name, tail = name[:i], name[i+1:]
-            else:
-                tail = ''
-            w = w.children[name]
-            name = tail
-        return w
-    _nametowidget = nametowidget
-    def _register(self, func, subst=None, needcleanup=1):
-        """Return a newly created Tcl function. If this
-        function is called, the Python function FUNC will
-        be executed. An optional function SUBST can
-        be given which will be executed before FUNC."""
-        f = CallWrapper(func, subst, self).__call__
-        name = repr(id(f))
-        try:
-            func = func.im_func
-        except AttributeError:
-            pass
-        try:
-            name = name + func.__name__
-        except AttributeError:
-            pass
-        self.tk.createcommand(name, f)
-        if needcleanup:
-            if self._tclCommands is None:
-                self._tclCommands = []
-            self._tclCommands.append(name)
-        #print '+ Tkinter created command', name
-        return name
-    register = _register
-    def _root(self):
-        """Internal function."""
-        w = self
-        while w.master: w = w.master
-        return w
-    _subst_format = ('%#', '%b', '%f', '%h', '%k',
-             '%s', '%t', '%w', '%x', '%y',
-             '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D')
-    _subst_format_str = " ".join(_subst_format)
-    def _substitute(self, *args):
-        """Internal function."""
-        if len(args) != len(self._subst_format): return args
-        getboolean = self.tk.getboolean
-
-        getint = int
-        def getint_event(s):
-            """Tk changed behavior in 8.4.2, returning "??" rather more often."""
-            try:
-                return int(s)
-            except ValueError:
-                return s
-
-        nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args
-        # Missing: (a, c, d, m, o, v, B, R)
-        e = Event()
-        # serial field: valid vor all events
-        # number of button: ButtonPress and ButtonRelease events only
-        # height field: Configure, ConfigureRequest, Create,
-        # ResizeRequest, and Expose events only
-        # keycode field: KeyPress and KeyRelease events only
-        # time field: "valid for events that contain a time field"
-        # width field: Configure, ConfigureRequest, Create, ResizeRequest,
-        # and Expose events only
-        # x field: "valid for events that contain a x field"
-        # y field: "valid for events that contain a y field"
-        # keysym as decimal: KeyPress and KeyRelease events only
-        # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress,
-        # KeyRelease,and Motion events
-        e.serial = getint(nsign)
-        e.num = getint_event(b)
-        try: e.focus = getboolean(f)
-        except TclError: pass
-        e.height = getint_event(h)
-        e.keycode = getint_event(k)
-        e.state = getint_event(s)
-        e.time = getint_event(t)
-        e.width = getint_event(w)
-        e.x = getint_event(x)
-        e.y = getint_event(y)
-        e.char = A
-        try: e.send_event = getboolean(E)
-        except TclError: pass
-        e.keysym = K
-        e.keysym_num = getint_event(N)
-        e.type = T
-        try:
-            e.widget = self._nametowidget(W)
-        except KeyError:
-            e.widget = W
-        e.x_root = getint_event(X)
-        e.y_root = getint_event(Y)
-        try:
-            e.delta = getint(D)
-        except ValueError:
-            e.delta = 0
-        return (e,)
-    def _report_exception(self):
-        """Internal function."""
-        import sys
-        exc, val, tb = sys.exc_type, sys.exc_value, sys.exc_traceback
-        root = self._root()
-        root.report_callback_exception(exc, val, tb)
-    def _configure(self, cmd, cnf, kw):
-        """Internal function."""
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        elif cnf:
-            cnf = _cnfmerge(cnf)
-        if cnf is None:
-            cnf = {}
-            for x in self.tk.split(
-                    self.tk.call(_flatten((self._w, cmd)))):
-                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
-            return cnf
-        if type(cnf) is StringType:
-            x = self.tk.split(
-                    self.tk.call(_flatten((self._w, cmd, '-'+cnf))))
-            return (x[0][1:],) + x[1:]
-        self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
-    # These used to be defined in Widget:
-    def configure(self, cnf=None, **kw):
-        """Configure resources of a widget.
-
-        The values for resources are specified as keyword
-        arguments. To get an overview about
-        the allowed keyword arguments call the method keys.
-        """
-        return self._configure('configure', cnf, kw)
-    config = configure
-    def cget(self, key):
-        """Return the resource value for a KEY given as string."""
-        return self.tk.call(self._w, 'cget', '-' + key)
-    __getitem__ = cget
-    def __setitem__(self, key, value):
-        self.configure({key: value})
-    def keys(self):
-        """Return a list of all resource names of this widget."""
-        return map(lambda x: x[0][1:],
-               self.tk.split(self.tk.call(self._w, 'configure')))
-    def __str__(self):
-        """Return the window path name of this widget."""
-        return self._w
-    # Pack methods that apply to the master
-    _noarg_ = ['_noarg_']
-    def pack_propagate(self, flag=_noarg_):
-        """Set or get the status for propagation of geometry information.
-
-        A boolean argument specifies whether the geometry information
-        of the slaves will determine the size of this widget. If no argument
-        is given the current setting will be returned.
-        """
-        if flag is Misc._noarg_:
-            return self._getboolean(self.tk.call(
-                'pack', 'propagate', self._w))
-        else:
-            self.tk.call('pack', 'propagate', self._w, flag)
-    propagate = pack_propagate
-    def pack_slaves(self):
-        """Return a list of all slaves of this widget
-        in its packing order."""
-        return map(self._nametowidget,
-               self.tk.splitlist(
-                   self.tk.call('pack', 'slaves', self._w)))
-    slaves = pack_slaves
-    # Place method that applies to the master
-    def place_slaves(self):
-        """Return a list of all slaves of this widget
-        in its packing order."""
-        return map(self._nametowidget,
-               self.tk.splitlist(
-                   self.tk.call(
-                       'place', 'slaves', self._w)))
-    # Grid methods that apply to the master
-    def grid_bbox(self, column=None, row=None, col2=None, row2=None):
-        """Return a tuple of integer coordinates for the bounding
-        box of this widget controlled by the geometry manager grid.
-
-        If COLUMN, ROW is given the bounding box applies from
-        the cell with row and column 0 to the specified
-        cell. If COL2 and ROW2 are given the bounding box
-        starts at that cell.
-
-        The returned integers specify the offset of the upper left
-        corner in the master widget and the width and height.
-        """
-        args = ('grid', 'bbox', self._w)
-        if column is not None and row is not None:
-            args = args + (column, row)
-        if col2 is not None and row2 is not None:
-            args = args + (col2, row2)
-        return self._getints(self.tk.call(*args)) or None
-
-    bbox = grid_bbox
-    def _grid_configure(self, command, index, cnf, kw):
-        """Internal function."""
-        if type(cnf) is StringType and not kw:
-            if cnf[-1:] == '_':
-                cnf = cnf[:-1]
-            if cnf[:1] != '-':
-                cnf = '-'+cnf
-            options = (cnf,)
-        else:
-            options = self._options(cnf, kw)
-        if not options:
-            res = self.tk.call('grid',
-                       command, self._w, index)
-            words = self.tk.splitlist(res)
-            dict = {}
-            for i in range(0, len(words), 2):
-                key = words[i][1:]
-                value = words[i+1]
-                if not value:
-                    value = None
-                elif '.' in value:
-                    value = getdouble(value)
-                else:
-                    value = getint(value)
-                dict[key] = value
-            return dict
-        res = self.tk.call(
-                  ('grid', command, self._w, index)
-                  + options)
-        if len(options) == 1:
-            if not res: return None
-            # In Tk 7.5, -width can be a float
-            if '.' in res: return getdouble(res)
-            return getint(res)
-    def grid_columnconfigure(self, index, cnf={}, **kw):
-        """Configure column INDEX of a grid.
-
-        Valid resources are minsize (minimum size of the column),
-        weight (how much does additional space propagate to this column)
-        and pad (how much space to let additionally)."""
-        return self._grid_configure('columnconfigure', index, cnf, kw)
-    columnconfigure = grid_columnconfigure
-    def grid_location(self, x, y):
-        """Return a tuple of column and row which identify the cell
-        at which the pixel at position X and Y inside the master
-        widget is located."""
-        return self._getints(
-            self.tk.call(
-                'grid', 'location', self._w, x, y)) or None
-    def grid_propagate(self, flag=_noarg_):
-        """Set or get the status for propagation of geometry information.
-
-        A boolean argument specifies whether the geometry information
-        of the slaves will determine the size of this widget. If no argument
-        is given, the current setting will be returned.
-        """
-        if flag is Misc._noarg_:
-            return self._getboolean(self.tk.call(
-                'grid', 'propagate', self._w))
-        else:
-            self.tk.call('grid', 'propagate', self._w, flag)
-    def grid_rowconfigure(self, index, cnf={}, **kw):
-        """Configure row INDEX of a grid.
-
-        Valid resources are minsize (minimum size of the row),
-        weight (how much does additional space propagate to this row)
-        and pad (how much space to let additionally)."""
-        return self._grid_configure('rowconfigure', index, cnf, kw)
-    rowconfigure = grid_rowconfigure
-    def grid_size(self):
-        """Return a tuple of the number of column and rows in the grid."""
-        return self._getints(
-            self.tk.call('grid', 'size', self._w)) or None
-    size = grid_size
-    def grid_slaves(self, row=None, column=None):
-        """Return a list of all slaves of this widget
-        in its packing order."""
-        args = ()
-        if row is not None:
-            args = args + ('-row', row)
-        if column is not None:
-            args = args + ('-column', column)
-        return map(self._nametowidget,
-               self.tk.splitlist(self.tk.call(
-                   ('grid', 'slaves', self._w) + args)))
-
-    # Support for the "event" command, new in Tk 4.2.
-    # By Case Roole.
-
-    def event_add(self, virtual, *sequences):
-        """Bind a virtual event VIRTUAL (of the form <<Name>>)
-        to an event SEQUENCE such that the virtual event is triggered
-        whenever SEQUENCE occurs."""
-        args = ('event', 'add', virtual) + sequences
-        self.tk.call(args)
-
-    def event_delete(self, virtual, *sequences):
-        """Unbind a virtual event VIRTUAL from SEQUENCE."""
-        args = ('event', 'delete', virtual) + sequences
-        self.tk.call(args)
-
-    def event_generate(self, sequence, **kw):
-        """Generate an event SEQUENCE. Additional
-        keyword arguments specify parameter of the event
-        (e.g. x, y, rootx, rooty)."""
-        args = ('event', 'generate', self._w, sequence)
-        for k, v in kw.items():
-            args = args + ('-%s' % k, str(v))
-        self.tk.call(args)
-
-    def event_info(self, virtual=None):
-        """Return a list of all virtual events or the information
-        about the SEQUENCE bound to the virtual event VIRTUAL."""
-        return self.tk.splitlist(
-            self.tk.call('event', 'info', virtual))
-
-    # Image related commands
-
-    def image_names(self):
-        """Return a list of all existing image names."""
-        return self.tk.call('image', 'names')
-
-    def image_types(self):
-        """Return a list of all available image types (e.g. phote bitmap)."""
-        return self.tk.call('image', 'types')
-
-
-class CallWrapper:
-    """Internal class. Stores function to call when some user
-    defined Tcl function is called e.g. after an event occurred."""
-    def __init__(self, func, subst, widget):
-        """Store FUNC, SUBST and WIDGET as members."""
-        self.func = func
-        self.subst = subst
-        self.widget = widget
-    def __call__(self, *args):
-        """Apply first function SUBST to arguments, than FUNC."""
-        try:
-            if self.subst:
-                args = self.subst(*args)
-            return self.func(*args)
-        except SystemExit, msg:
-            raise SystemExit, msg
-        except:
-            self.widget._report_exception()
-
-
-class Wm:
-    """Provides functions for the communication with the window manager."""
-
-    def wm_aspect(self,
-              minNumer=None, minDenom=None,
-              maxNumer=None, maxDenom=None):
-        """Instruct the window manager to set the aspect ratio (width/height)
-        of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple
-        of the actual values if no argument is given."""
-        return self._getints(
-            self.tk.call('wm', 'aspect', self._w,
-                     minNumer, minDenom,
-                     maxNumer, maxDenom))
-    aspect = wm_aspect
-
-    def wm_attributes(self, *args):
-        """This subcommand returns or sets platform specific attributes
-
-        The first form returns a list of the platform specific flags and
-        their values. The second form returns the value for the specific
-        option. The third form sets one or more of the values. The values
-        are as follows:
-
-        On Windows, -disabled gets or sets whether the window is in a
-        disabled state. -toolwindow gets or sets the style of the window
-        to toolwindow (as defined in the MSDN). -topmost gets or sets
-        whether this is a topmost window (displays above all other
-        windows).
-
-        On Macintosh, XXXXX
-
-        On Unix, there are currently no special attribute values.
-        """
-        args = ('wm', 'attributes', self._w) + args
-        return self.tk.call(args)
-    attributes=wm_attributes
-
-    def wm_client(self, name=None):
-        """Store NAME in WM_CLIENT_MACHINE property of this widget. Return
-        current value."""
-        return self.tk.call('wm', 'client', self._w, name)
-    client = wm_client
-    def wm_colormapwindows(self, *wlist):
-        """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property
-        of this widget. This list contains windows whose colormaps differ from their
-        parents. Return current list of widgets if WLIST is empty."""
-        if len(wlist) > 1:
-            wlist = (wlist,) # Tk needs a list of windows here
-        args = ('wm', 'colormapwindows', self._w) + wlist
-        return map(self._nametowidget, self.tk.call(args))
-    colormapwindows = wm_colormapwindows
-    def wm_command(self, value=None):
-        """Store VALUE in WM_COMMAND property. It is the command
-        which shall be used to invoke the application. Return current
-        command if VALUE is None."""
-        return self.tk.call('wm', 'command', self._w, value)
-    command = wm_command
-    def wm_deiconify(self):
-        """Deiconify this widget. If it was never mapped it will not be mapped.
-        On Windows it will raise this widget and give it the focus."""
-        return self.tk.call('wm', 'deiconify', self._w)
-    deiconify = wm_deiconify
-    def wm_focusmodel(self, model=None):
-        """Set focus model to MODEL. "active" means that this widget will claim
-        the focus itself, "passive" means that the window manager shall give
-        the focus. Return current focus model if MODEL is None."""
-        return self.tk.call('wm', 'focusmodel', self._w, model)
-    focusmodel = wm_focusmodel
-    def wm_frame(self):
-        """Return identifier for decorative frame of this widget if present."""
-        return self.tk.call('wm', 'frame', self._w)
-    frame = wm_frame
-    def wm_geometry(self, newGeometry=None):
-        """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return
-        current value if None is given."""
-        return self.tk.call('wm', 'geometry', self._w, newGeometry)
-    geometry = wm_geometry
-    def wm_grid(self,
-         baseWidth=None, baseHeight=None,
-         widthInc=None, heightInc=None):
-        """Instruct the window manager that this widget shall only be
-        resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and
-        height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the
-        number of grid units requested in Tk_GeometryRequest."""
-        return self._getints(self.tk.call(
-            'wm', 'grid', self._w,
-            baseWidth, baseHeight, widthInc, heightInc))
-    grid = wm_grid
-    def wm_group(self, pathName=None):
-        """Set the group leader widgets for related widgets to PATHNAME. Return
-        the group leader of this widget if None is given."""
-        return self.tk.call('wm', 'group', self._w, pathName)
-    group = wm_group
-    def wm_iconbitmap(self, bitmap=None, default=None):
-        """Set bitmap for the iconified widget to BITMAP. Return
-        the bitmap if None is given.
-
-        Under Windows, the DEFAULT parameter can be used to set the icon
-        for the widget and any descendents that don't have an icon set
-        explicitly.  DEFAULT can be the relative path to a .ico file
-        (example: root.iconbitmap(default='myicon.ico') ).  See Tk
-        documentation for more information."""
-        if default:
-            return self.tk.call('wm', 'iconbitmap', self._w, '-default', default)
-        else:
-            return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
-    iconbitmap = wm_iconbitmap
-    def wm_iconify(self):
-        """Display widget as icon."""
-        return self.tk.call('wm', 'iconify', self._w)
-    iconify = wm_iconify
-    def wm_iconmask(self, bitmap=None):
-        """Set mask for the icon bitmap of this widget. Return the
-        mask if None is given."""
-        return self.tk.call('wm', 'iconmask', self._w, bitmap)
-    iconmask = wm_iconmask
-    def wm_iconname(self, newName=None):
-        """Set the name of the icon for this widget. Return the name if
-        None is given."""
-        return self.tk.call('wm', 'iconname', self._w, newName)
-    iconname = wm_iconname
-    def wm_iconposition(self, x=None, y=None):
-        """Set the position of the icon of this widget to X and Y. Return
-        a tuple of the current values of X and X if None is given."""
-        return self._getints(self.tk.call(
-            'wm', 'iconposition', self._w, x, y))
-    iconposition = wm_iconposition
-    def wm_iconwindow(self, pathName=None):
-        """Set widget PATHNAME to be displayed instead of icon. Return the current
-        value if None is given."""
-        return self.tk.call('wm', 'iconwindow', self._w, pathName)
-    iconwindow = wm_iconwindow
-    def wm_maxsize(self, width=None, height=None):
-        """Set max WIDTH and HEIGHT for this widget. If the window is gridded
-        the values are given in grid units. Return the current values if None
-        is given."""
-        return self._getints(self.tk.call(
-            'wm', 'maxsize', self._w, width, height))
-    maxsize = wm_maxsize
-    def wm_minsize(self, width=None, height=None):
-        """Set min WIDTH and HEIGHT for this widget. If the window is gridded
-        the values are given in grid units. Return the current values if None
-        is given."""
-        return self._getints(self.tk.call(
-            'wm', 'minsize', self._w, width, height))
-    minsize = wm_minsize
-    def wm_overrideredirect(self, boolean=None):
-        """Instruct the window manager to ignore this widget
-        if BOOLEAN is given with 1. Return the current value if None
-        is given."""
-        return self._getboolean(self.tk.call(
-            'wm', 'overrideredirect', self._w, boolean))
-    overrideredirect = wm_overrideredirect
-    def wm_positionfrom(self, who=None):
-        """Instruct the window manager that the position of this widget shall
-        be defined by the user if WHO is "user", and by its own policy if WHO is
-        "program"."""
-        return self.tk.call('wm', 'positionfrom', self._w, who)
-    positionfrom = wm_positionfrom
-    def wm_protocol(self, name=None, func=None):
-        """Bind function FUNC to command NAME for this widget.
-        Return the function bound to NAME if None is given. NAME could be
-        e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW"."""
-        if callable(func):
-            command = self._register(func)
-        else:
-            command = func
-        return self.tk.call(
-            'wm', 'protocol', self._w, name, command)
-    protocol = wm_protocol
-    def wm_resizable(self, width=None, height=None):
-        """Instruct the window manager whether this width can be resized
-        in WIDTH or HEIGHT. Both values are boolean values."""
-        return self.tk.call('wm', 'resizable', self._w, width, height)
-    resizable = wm_resizable
-    def wm_sizefrom(self, who=None):
-        """Instruct the window manager that the size of this widget shall
-        be defined by the user if WHO is "user", and by its own policy if WHO is
-        "program"."""
-        return self.tk.call('wm', 'sizefrom', self._w, who)
-    sizefrom = wm_sizefrom
-    def wm_state(self, newstate=None):
-        """Query or set the state of this widget as one of normal, icon,
-        iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only)."""
-        return self.tk.call('wm', 'state', self._w, newstate)
-    state = wm_state
-    def wm_title(self, string=None):
-        """Set the title of this widget."""
-        return self.tk.call('wm', 'title', self._w, string)
-    title = wm_title
-    def wm_transient(self, master=None):
-        """Instruct the window manager that this widget is transient
-        with regard to widget MASTER."""
-        return self.tk.call('wm', 'transient', self._w, master)
-    transient = wm_transient
-    def wm_withdraw(self):
-        """Withdraw this widget from the screen such that it is unmapped
-        and forgotten by the window manager. Re-draw it with wm_deiconify."""
-        return self.tk.call('wm', 'withdraw', self._w)
-    withdraw = wm_withdraw
-
-
-class Tk(Misc, Wm):
-    """Toplevel widget of Tk which represents mostly the main window
-    of an appliation. It has an associated Tcl interpreter."""
-    _w = '.'
-    def __init__(self, screenName=None, baseName=None, className='Tk',
-                 useTk=1, sync=0, use=None):
-        """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will
-        be created. BASENAME will be used for the identification of the profile file (see
-        readprofile).
-        It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
-        is the name of the widget class."""
-        self.master = None
-        self.children = {}
-        self._tkloaded = 0
-        # to avoid recursions in the getattr code in case of failure, we
-        # ensure that self.tk is always _something_.
-        self.tk = None
-        if baseName is None:
-            import sys, os
-            baseName = os.path.basename(sys.argv[0])
-            baseName, ext = os.path.splitext(baseName)
-            if ext not in ('.py', '.pyc', '.pyo'):
-                baseName = baseName + ext
-        interactive = 0
-        self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
-        if useTk:
-            self._loadtk()
-        self.readprofile(baseName, className)
-    def loadtk(self):
-        if not self._tkloaded:
-            self.tk.loadtk()
-            self._loadtk()
-    def _loadtk(self):
-        self._tkloaded = 1
-        global _default_root
-        if _MacOS and hasattr(_MacOS, 'SchedParams'):
-            # Disable event scanning except for Command-Period
-            _MacOS.SchedParams(1, 0)
-            # Work around nasty MacTk bug
-            # XXX Is this one still needed?
-            self.update()
-        # Version sanity checks
-        tk_version = self.tk.getvar('tk_version')
-        if tk_version != _tkinter.TK_VERSION:
-            raise RuntimeError, \
-            "tk.h version (%s) doesn't match libtk.a version (%s)" \
-            % (_tkinter.TK_VERSION, tk_version)
-        # Under unknown circumstances, tcl_version gets coerced to float
-        tcl_version = str(self.tk.getvar('tcl_version'))
-        if tcl_version != _tkinter.TCL_VERSION:
-            raise RuntimeError, \
-            "tcl.h version (%s) doesn't match libtcl.a version (%s)" \
-            % (_tkinter.TCL_VERSION, tcl_version)
-        if TkVersion < 4.0:
-            raise RuntimeError, \
-            "Tk 4.0 or higher is required; found Tk %s" \
-            % str(TkVersion)
-        # Create and register the tkerror and exit commands
-        # We need to inline parts of _register here, _ register
-        # would register differently-named commands.
-        if self._tclCommands is None:
-            self._tclCommands = []
-        self.tk.createcommand('tkerror', _tkerror)
-        self.tk.createcommand('exit', _exit)
-        self._tclCommands.append('tkerror')
-        self._tclCommands.append('exit')
-        if _support_default_root and not _default_root:
-            _default_root = self
-        self.protocol("WM_DELETE_WINDOW", self.destroy)
-    def destroy(self):
-        """Destroy this and all descendants widgets. This will
-        end the application of this Tcl interpreter."""
-        for c in self.children.values(): c.destroy()
-        self.tk.call('destroy', self._w)
-        Misc.destroy(self)
-        global _default_root
-        if _support_default_root and _default_root is self:
-            _default_root = None
-    def readprofile(self, baseName, className):
-        """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into
-        the Tcl Interpreter and calls execfile on BASENAME.py and CLASSNAME.py if
-        such a file exists in the home directory."""
-        import os
-        if os.environ.has_key('HOME'): home = os.environ['HOME']
-        else: home = os.curdir
-        class_tcl = os.path.join(home, '.%s.tcl' % className)
-        class_py = os.path.join(home, '.%s.py' % className)
-        base_tcl = os.path.join(home, '.%s.tcl' % baseName)
-        base_py = os.path.join(home, '.%s.py' % baseName)
-        dir = {'self': self}
-        exec 'from tkinter import *' in dir
-        if os.path.isfile(class_tcl):
-            self.tk.call('source', class_tcl)
-        if os.path.isfile(class_py):
-            execfile(class_py, dir)
-        if os.path.isfile(base_tcl):
-            self.tk.call('source', base_tcl)
-        if os.path.isfile(base_py):
-            execfile(base_py, dir)
-    def report_callback_exception(self, exc, val, tb):
-        """Internal function. It reports exception on sys.stderr."""
-        import traceback, sys
-        sys.stderr.write("Exception in Tkinter callback\n")
-        sys.last_type = exc
-        sys.last_value = val
-        sys.last_traceback = tb
-        traceback.print_exception(exc, val, tb)
-    def __getattr__(self, attr):
-        "Delegate attribute access to the interpreter object"
-        return getattr(self.tk, attr)
-
-# Ideally, the classes Pack, Place and Grid disappear, the
-# pack/place/grid methods are defined on the Widget class, and
-# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
-# ...), with pack(), place() and grid() being short for
-# pack_configure(), place_configure() and grid_columnconfigure(), and
-# forget() being short for pack_forget().  As a practical matter, I'm
-# afraid that there is too much code out there that may be using the
-# Pack, Place or Grid class, so I leave them intact -- but only as
-# backwards compatibility features.  Also note that those methods that
-# take a master as argument (e.g. pack_propagate) have been moved to
-# the Misc class (which now incorporates all methods common between
-# toplevel and interior widgets).  Again, for compatibility, these are
-# copied into the Pack, Place or Grid class.
-
-
-def Tcl(screenName=None, baseName=None, className='Tk', useTk=0):
-    return Tk(screenName, baseName, className, useTk)
-
-class Pack:
-    """Geometry manager Pack.
-
-    Base class to use the methods pack_* in every widget."""
-    def pack_configure(self, cnf={}, **kw):
-        """Pack a widget in the parent widget. Use as options:
-        after=widget - pack it after you have packed widget
-        anchor=NSEW (or subset) - position widget according to
-                                  given direction
-                before=widget - pack it before you will pack widget
-        expand=bool - expand widget if parent size grows
-        fill=NONE or X or Y or BOTH - fill widget if widget grows
-        in=master - use master to contain this widget
-        ipadx=amount - add internal padding in x direction
-        ipady=amount - add internal padding in y direction
-        padx=amount - add padding in x direction
-        pady=amount - add padding in y direction
-        side=TOP or BOTTOM or LEFT or RIGHT -  where to add this widget.
-        """
-        self.tk.call(
-              ('pack', 'configure', self._w)
-              + self._options(cnf, kw))
-    pack = configure = config = pack_configure
-    def pack_forget(self):
-        """Unmap this widget and do not use it for the packing order."""
-        self.tk.call('pack', 'forget', self._w)
-    forget = pack_forget
-    def pack_info(self):
-        """Return information about the packing options
-        for this widget."""
-        words = self.tk.splitlist(
-            self.tk.call('pack', 'info', self._w))
-        dict = {}
-        for i in range(0, len(words), 2):
-            key = words[i][1:]
-            value = words[i+1]
-            if value[:1] == '.':
-                value = self._nametowidget(value)
-            dict[key] = value
-        return dict
-    info = pack_info
-    propagate = pack_propagate = Misc.pack_propagate
-    slaves = pack_slaves = Misc.pack_slaves
-
-class Place:
-    """Geometry manager Place.
-
-    Base class to use the methods place_* in every widget."""
-    def place_configure(self, cnf={}, **kw):
-        """Place a widget in the parent widget. Use as options:
-        in=master - master relative to which the widget is placed.
-        x=amount - locate anchor of this widget at position x of master
-        y=amount - locate anchor of this widget at position y of master
-        relx=amount - locate anchor of this widget between 0.0 and 1.0
-                      relative to width of master (1.0 is right edge)
-            rely=amount - locate anchor of this widget between 0.0 and 1.0
-                      relative to height of master (1.0 is bottom edge)
-            anchor=NSEW (or subset) - position anchor according to given direction
-        width=amount - width of this widget in pixel
-        height=amount - height of this widget in pixel
-        relwidth=amount - width of this widget between 0.0 and 1.0
-                          relative to width of master (1.0 is the same width
-                  as the master)
-            relheight=amount - height of this widget between 0.0 and 1.0
-                           relative to height of master (1.0 is the same
-                   height as the master)
-            bordermode="inside" or "outside" - whether to take border width of master widget
-                                               into account
-            """
-        for k in ['in_']:
-            if kw.has_key(k):
-                kw[k[:-1]] = kw[k]
-                del kw[k]
-        self.tk.call(
-              ('place', 'configure', self._w)
-              + self._options(cnf, kw))
-    place = configure = config = place_configure
-    def place_forget(self):
-        """Unmap this widget."""
-        self.tk.call('place', 'forget', self._w)
-    forget = place_forget
-    def place_info(self):
-        """Return information about the placing options
-        for this widget."""
-        words = self.tk.splitlist(
-            self.tk.call('place', 'info', self._w))
-        dict = {}
-        for i in range(0, len(words), 2):
-            key = words[i][1:]
-            value = words[i+1]
-            if value[:1] == '.':
-                value = self._nametowidget(value)
-            dict[key] = value
-        return dict
-    info = place_info
-    slaves = place_slaves = Misc.place_slaves
-
-class Grid:
-    """Geometry manager Grid.
-
-    Base class to use the methods grid_* in every widget."""
-    # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
-    def grid_configure(self, cnf={}, **kw):
-        """Position a widget in the parent widget in a grid. Use as options:
-        column=number - use cell identified with given column (starting with 0)
-        columnspan=number - this widget will span several columns
-        in=master - use master to contain this widget
-        ipadx=amount - add internal padding in x direction
-        ipady=amount - add internal padding in y direction
-        padx=amount - add padding in x direction
-        pady=amount - add padding in y direction
-        row=number - use cell identified with given row (starting with 0)
-        rowspan=number - this widget will span several rows
-        sticky=NSEW - if cell is larger on which sides will this
-                      widget stick to the cell boundary
-        """
-        self.tk.call(
-              ('grid', 'configure', self._w)
-              + self._options(cnf, kw))
-    grid = configure = config = grid_configure
-    bbox = grid_bbox = Misc.grid_bbox
-    columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
-    def grid_forget(self):
-        """Unmap this widget."""
-        self.tk.call('grid', 'forget', self._w)
-    forget = grid_forget
-    def grid_remove(self):
-        """Unmap this widget but remember the grid options."""
-        self.tk.call('grid', 'remove', self._w)
-    def grid_info(self):
-        """Return information about the options
-        for positioning this widget in a grid."""
-        words = self.tk.splitlist(
-            self.tk.call('grid', 'info', self._w))
-        dict = {}
-        for i in range(0, len(words), 2):
-            key = words[i][1:]
-            value = words[i+1]
-            if value[:1] == '.':
-                value = self._nametowidget(value)
-            dict[key] = value
-        return dict
-    info = grid_info
-    location = grid_location = Misc.grid_location
-    propagate = grid_propagate = Misc.grid_propagate
-    rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
-    size = grid_size = Misc.grid_size
-    slaves = grid_slaves = Misc.grid_slaves
-
-class BaseWidget(Misc):
-    """Internal class."""
-    def _setup(self, master, cnf):
-        """Internal function. Sets up information about children."""
-        if _support_default_root:
-            global _default_root
-            if not master:
-                if not _default_root:
-                    _default_root = Tk()
-                master = _default_root
-        self.master = master
-        self.tk = master.tk
-        name = None
-        if cnf.has_key('name'):
-            name = cnf['name']
-            del cnf['name']
-        if not name:
-            name = repr(id(self))
-        self._name = name
-        if master._w=='.':
-            self._w = '.' + name
-        else:
-            self._w = master._w + '.' + name
-        self.children = {}
-        if self.master.children.has_key(self._name):
-            self.master.children[self._name].destroy()
-        self.master.children[self._name] = self
-    def __init__(self, master, widgetName, cnf={}, kw={}, extra=()):
-        """Construct a widget with the parent widget MASTER, a name WIDGETNAME
-        and appropriate options."""
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        self.widgetName = widgetName
-        BaseWidget._setup(self, master, cnf)
-        classes = []
-        for k in cnf.keys():
-            if type(k) is ClassType:
-                classes.append((k, cnf[k]))
-                del cnf[k]
-        self.tk.call(
-            (widgetName, self._w) + extra + self._options(cnf))
-        for k, v in classes:
-            k.configure(self, v)
-    def destroy(self):
-        """Destroy this and all descendants widgets."""
-        for c in self.children.values(): c.destroy()
-        self.tk.call('destroy', self._w)
-        if self.master.children.has_key(self._name):
-            del self.master.children[self._name]
-        Misc.destroy(self)
-    def _do(self, name, args=()):
-        # XXX Obsolete -- better use self.tk.call directly!
-        return self.tk.call((self._w, name) + args)
-
-class Widget(BaseWidget, Pack, Place, Grid):
-    """Internal class.
-
-    Base class for a widget which can be positioned with the geometry managers
-    Pack, Place or Grid."""
-    pass
-
-class Toplevel(BaseWidget, Wm):
-    """Toplevel widget, e.g. for dialogs."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a toplevel widget with the parent MASTER.
-
-        Valid resource names: background, bd, bg, borderwidth, class,
-        colormap, container, cursor, height, highlightbackground,
-        highlightcolor, highlightthickness, menu, relief, screen, takefocus,
-        use, visual, width."""
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        extra = ()
-        for wmkey in ['screen', 'class_', 'class', 'visual',
-                  'colormap']:
-            if cnf.has_key(wmkey):
-                val = cnf[wmkey]
-                # TBD: a hack needed because some keys
-                # are not valid as keyword arguments
-                if wmkey[-1] == '_': opt = '-'+wmkey[:-1]
-                else: opt = '-'+wmkey
-                extra = extra + (opt, val)
-                del cnf[wmkey]
-        BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
-        root = self._root()
-        self.iconname(root.iconname())
-        self.title(root.title())
-        self.protocol("WM_DELETE_WINDOW", self.destroy)
-
-class Button(Widget):
-    """Button widget."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a button widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            activebackground, activeforeground, anchor,
-            background, bitmap, borderwidth, cursor,
-            disabledforeground, font, foreground
-            highlightbackground, highlightcolor,
-            highlightthickness, image, justify,
-            padx, pady, relief, repeatdelay,
-            repeatinterval, takefocus, text,
-            textvariable, underline, wraplength
-
-        WIDGET-SPECIFIC OPTIONS
-
-            command, compound, default, height,
-            overrelief, state, width
-        """
-        Widget.__init__(self, master, 'button', cnf, kw)
-
-    def tkButtonEnter(self, *dummy):
-        self.tk.call('tkButtonEnter', self._w)
-
-    def tkButtonLeave(self, *dummy):
-        self.tk.call('tkButtonLeave', self._w)
-
-    def tkButtonDown(self, *dummy):
-        self.tk.call('tkButtonDown', self._w)
-
-    def tkButtonUp(self, *dummy):
-        self.tk.call('tkButtonUp', self._w)
-
-    def tkButtonInvoke(self, *dummy):
-        self.tk.call('tkButtonInvoke', self._w)
-
-    def flash(self):
-        """Flash the button.
-
-        This is accomplished by redisplaying
-        the button several times, alternating between active and
-        normal colors. At the end of the flash the button is left
-        in the same normal/active state as when the command was
-        invoked. This command is ignored if the button's state is
-        disabled.
-        """
-        self.tk.call(self._w, 'flash')
-
-    def invoke(self):
-        """Invoke the command associated with the button.
-
-        The return value is the return value from the command,
-        or an empty string if there is no command associated with
-        the button. This command is ignored if the button's state
-        is disabled.
-        """
-        return self.tk.call(self._w, 'invoke')
-
-# Indices:
-# XXX I don't like these -- take them away
-def AtEnd():
-    return 'end'
-def AtInsert(*args):
-    s = 'insert'
-    for a in args:
-        if a: s = s + (' ' + a)
-    return s
-def AtSelFirst():
-    return 'sel.first'
-def AtSelLast():
-    return 'sel.last'
-def At(x, y=None):
-    if y is None:
-        return '@%r' % (x,)
-    else:
-        return '@%r,%r' % (x, y)
-
-class Canvas(Widget):
-    """Canvas widget to display graphical elements like lines or text."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a canvas widget with the parent MASTER.
-
-        Valid resource names: background, bd, bg, borderwidth, closeenough,
-        confine, cursor, height, highlightbackground, highlightcolor,
-        highlightthickness, insertbackground, insertborderwidth,
-        insertofftime, insertontime, insertwidth, offset, relief,
-        scrollregion, selectbackground, selectborderwidth, selectforeground,
-        state, takefocus, width, xscrollcommand, xscrollincrement,
-        yscrollcommand, yscrollincrement."""
-        Widget.__init__(self, master, 'canvas', cnf, kw)
-    def addtag(self, *args):
-        """Internal function."""
-        self.tk.call((self._w, 'addtag') + args)
-    def addtag_above(self, newtag, tagOrId):
-        """Add tag NEWTAG to all items above TAGORID."""
-        self.addtag(newtag, 'above', tagOrId)
-    def addtag_all(self, newtag):
-        """Add tag NEWTAG to all items."""
-        self.addtag(newtag, 'all')
-    def addtag_below(self, newtag, tagOrId):
-        """Add tag NEWTAG to all items below TAGORID."""
-        self.addtag(newtag, 'below', tagOrId)
-    def addtag_closest(self, newtag, x, y, halo=None, start=None):
-        """Add tag NEWTAG to item which is closest to pixel at X, Y.
-        If several match take the top-most.
-        All items closer than HALO are considered overlapping (all are
-        closests). If START is specified the next below this tag is taken."""
-        self.addtag(newtag, 'closest', x, y, halo, start)
-    def addtag_enclosed(self, newtag, x1, y1, x2, y2):
-        """Add tag NEWTAG to all items in the rectangle defined
-        by X1,Y1,X2,Y2."""
-        self.addtag(newtag, 'enclosed', x1, y1, x2, y2)
-    def addtag_overlapping(self, newtag, x1, y1, x2, y2):
-        """Add tag NEWTAG to all items which overlap the rectangle
-        defined by X1,Y1,X2,Y2."""
-        self.addtag(newtag, 'overlapping', x1, y1, x2, y2)
-    def addtag_withtag(self, newtag, tagOrId):
-        """Add tag NEWTAG to all items with TAGORID."""
-        self.addtag(newtag, 'withtag', tagOrId)
-    def bbox(self, *args):
-        """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
-        which encloses all items with tags specified as arguments."""
-        return self._getints(
-            self.tk.call((self._w, 'bbox') + args)) or None
-    def tag_unbind(self, tagOrId, sequence, funcid=None):
-        """Unbind for all items with TAGORID for event SEQUENCE  the
-        function identified with FUNCID."""
-        self.tk.call(self._w, 'bind', tagOrId, sequence, '')
-        if funcid:
-            self.deletecommand(funcid)
-    def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
-        """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
-
-        An additional boolean parameter ADD specifies whether FUNC will be
-        called additionally to the other bound function or whether it will
-        replace the previous function. See bind for the return value."""
-        return self._bind((self._w, 'bind', tagOrId),
-                  sequence, func, add)
-    def canvasx(self, screenx, gridspacing=None):
-        """Return the canvas x coordinate of pixel position SCREENX rounded
-        to nearest multiple of GRIDSPACING units."""
-        return getdouble(self.tk.call(
-            self._w, 'canvasx', screenx, gridspacing))
-    def canvasy(self, screeny, gridspacing=None):
-        """Return the canvas y coordinate of pixel position SCREENY rounded
-        to nearest multiple of GRIDSPACING units."""
-        return getdouble(self.tk.call(
-            self._w, 'canvasy', screeny, gridspacing))
-    def coords(self, *args):
-        """Return a list of coordinates for the item given in ARGS."""
-        # XXX Should use _flatten on args
-        return map(getdouble,
-                           self.tk.splitlist(
-                   self.tk.call((self._w, 'coords') + args)))
-    def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={})
-        """Internal function."""
-        args = _flatten(args)
-        cnf = args[-1]
-        if type(cnf) in (DictionaryType, TupleType):
-            args = args[:-1]
-        else:
-            cnf = {}
-        return getint(self.tk.call(
-            self._w, 'create', itemType,
-            *(args + self._options(cnf, kw))))
-    def create_arc(self, *args, **kw):
-        """Create arc shaped region with coordinates x1,y1,x2,y2."""
-        return self._create('arc', args, kw)
-    def create_bitmap(self, *args, **kw):
-        """Create bitmap with coordinates x1,y1."""
-        return self._create('bitmap', args, kw)
-    def create_image(self, *args, **kw):
-        """Create image item with coordinates x1,y1."""
-        return self._create('image', args, kw)
-    def create_line(self, *args, **kw):
-        """Create line with coordinates x1,y1,...,xn,yn."""
-        return self._create('line', args, kw)
-    def create_oval(self, *args, **kw):
-        """Create oval with coordinates x1,y1,x2,y2."""
-        return self._create('oval', args, kw)
-    def create_polygon(self, *args, **kw):
-        """Create polygon with coordinates x1,y1,...,xn,yn."""
-        return self._create('polygon', args, kw)
-    def create_rectangle(self, *args, **kw):
-        """Create rectangle with coordinates x1,y1,x2,y2."""
-        return self._create('rectangle', args, kw)
-    def create_text(self, *args, **kw):
-        """Create text with coordinates x1,y1."""
-        return self._create('text', args, kw)
-    def create_window(self, *args, **kw):
-        """Create window with coordinates x1,y1,x2,y2."""
-        return self._create('window', args, kw)
-    def dchars(self, *args):
-        """Delete characters of text items identified by tag or id in ARGS (possibly
-        several times) from FIRST to LAST character (including)."""
-        self.tk.call((self._w, 'dchars') + args)
-    def delete(self, *args):
-        """Delete items identified by all tag or ids contained in ARGS."""
-        self.tk.call((self._w, 'delete') + args)
-    def dtag(self, *args):
-        """Delete tag or id given as last arguments in ARGS from items
-        identified by first argument in ARGS."""
-        self.tk.call((self._w, 'dtag') + args)
-    def find(self, *args):
-        """Internal function."""
-        return self._getints(
-            self.tk.call((self._w, 'find') + args)) or ()
-    def find_above(self, tagOrId):
-        """Return items above TAGORID."""
-        return self.find('above', tagOrId)
-    def find_all(self):
-        """Return all items."""
-        return self.find('all')
-    def find_below(self, tagOrId):
-        """Return all items below TAGORID."""
-        return self.find('below', tagOrId)
-    def find_closest(self, x, y, halo=None, start=None):
-        """Return item which is closest to pixel at X, Y.
-        If several match take the top-most.
-        All items closer than HALO are considered overlapping (all are
-        closests). If START is specified the next below this tag is taken."""
-        return self.find('closest', x, y, halo, start)
-    def find_enclosed(self, x1, y1, x2, y2):
-        """Return all items in rectangle defined
-        by X1,Y1,X2,Y2."""
-        return self.find('enclosed', x1, y1, x2, y2)
-    def find_overlapping(self, x1, y1, x2, y2):
-        """Return all items which overlap the rectangle
-        defined by X1,Y1,X2,Y2."""
-        return self.find('overlapping', x1, y1, x2, y2)
-    def find_withtag(self, tagOrId):
-        """Return all items with TAGORID."""
-        return self.find('withtag', tagOrId)
-    def focus(self, *args):
-        """Set focus to the first item specified in ARGS."""
-        return self.tk.call((self._w, 'focus') + args)
-    def gettags(self, *args):
-        """Return tags associated with the first item specified in ARGS."""
-        return self.tk.splitlist(
-            self.tk.call((self._w, 'gettags') + args))
-    def icursor(self, *args):
-        """Set cursor at position POS in the item identified by TAGORID.
-        In ARGS TAGORID must be first."""
-        self.tk.call((self._w, 'icursor') + args)
-    def index(self, *args):
-        """Return position of cursor as integer in item specified in ARGS."""
-        return getint(self.tk.call((self._w, 'index') + args))
-    def insert(self, *args):
-        """Insert TEXT in item TAGORID at position POS. ARGS must
-        be TAGORID POS TEXT."""
-        self.tk.call((self._w, 'insert') + args)
-    def itemcget(self, tagOrId, option):
-        """Return the resource value for an OPTION for item TAGORID."""
-        return self.tk.call(
-            (self._w, 'itemcget') + (tagOrId, '-'+option))
-    def itemconfigure(self, tagOrId, cnf=None, **kw):
-        """Configure resources of an item TAGORID.
-
-        The values for resources are specified as keyword
-        arguments. To get an overview about
-        the allowed keyword arguments call the method without arguments.
-        """
-        return self._configure(('itemconfigure', tagOrId), cnf, kw)
-    itemconfig = itemconfigure
-    # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift,
-    # so the preferred name for them is tag_lower, tag_raise
-    # (similar to tag_bind, and similar to the Text widget);
-    # unfortunately can't delete the old ones yet (maybe in 1.6)
-    def tag_lower(self, *args):
-        """Lower an item TAGORID given in ARGS
-        (optional below another item)."""
-        self.tk.call((self._w, 'lower') + args)
-    lower = tag_lower
-    def move(self, *args):
-        """Move an item TAGORID given in ARGS."""
-        self.tk.call((self._w, 'move') + args)
-    def postscript(self, cnf={}, **kw):
-        """Print the contents of the canvas to a postscript
-        file. Valid options: colormap, colormode, file, fontmap,
-        height, pageanchor, pageheight, pagewidth, pagex, pagey,
-        rotate, witdh, x, y."""
-        return self.tk.call((self._w, 'postscript') +
-                    self._options(cnf, kw))
-    def tag_raise(self, *args):
-        """Raise an item TAGORID given in ARGS
-        (optional above another item)."""
-        self.tk.call((self._w, 'raise') + args)
-    lift = tkraise = tag_raise
-    def scale(self, *args):
-        """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE."""
-        self.tk.call((self._w, 'scale') + args)
-    def scan_mark(self, x, y):
-        """Remember the current X, Y coordinates."""
-        self.tk.call(self._w, 'scan', 'mark', x, y)
-    def scan_dragto(self, x, y, gain=10):
-        """Adjust the view of the canvas to GAIN times the
-        difference between X and Y and the coordinates given in
-        scan_mark."""
-        self.tk.call(self._w, 'scan', 'dragto', x, y, gain)
-    def select_adjust(self, tagOrId, index):
-        """Adjust the end of the selection near the cursor of an item TAGORID to index."""
-        self.tk.call(self._w, 'select', 'adjust', tagOrId, index)
-    def select_clear(self):
-        """Clear the selection if it is in this widget."""
-        self.tk.call(self._w, 'select', 'clear')
-    def select_from(self, tagOrId, index):
-        """Set the fixed end of a selection in item TAGORID to INDEX."""
-        self.tk.call(self._w, 'select', 'from', tagOrId, index)
-    def select_item(self):
-        """Return the item which has the selection."""
-        return self.tk.call(self._w, 'select', 'item') or None
-    def select_to(self, tagOrId, index):
-        """Set the variable end of a selection in item TAGORID to INDEX."""
-        self.tk.call(self._w, 'select', 'to', tagOrId, index)
-    def type(self, tagOrId):
-        """Return the type of the item TAGORID."""
-        return self.tk.call(self._w, 'type', tagOrId) or None
-    def xview(self, *args):
-        """Query and change horizontal position of the view."""
-        if not args:
-            return self._getdoubles(self.tk.call(self._w, 'xview'))
-        self.tk.call((self._w, 'xview') + args)
-    def xview_moveto(self, fraction):
-        """Adjusts the view in the window so that FRACTION of the
-        total width of the canvas is off-screen to the left."""
-        self.tk.call(self._w, 'xview', 'moveto', fraction)
-    def xview_scroll(self, number, what):
-        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'xview', 'scroll', number, what)
-    def yview(self, *args):
-        """Query and change vertical position of the view."""
-        if not args:
-            return self._getdoubles(self.tk.call(self._w, 'yview'))
-        self.tk.call((self._w, 'yview') + args)
-    def yview_moveto(self, fraction):
-        """Adjusts the view in the window so that FRACTION of the
-        total height of the canvas is off-screen to the top."""
-        self.tk.call(self._w, 'yview', 'moveto', fraction)
-    def yview_scroll(self, number, what):
-        """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'yview', 'scroll', number, what)
-
-class Checkbutton(Widget):
-    """Checkbutton widget which is either in on- or off-state."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a checkbutton widget with the parent MASTER.
-
-        Valid resource names: activebackground, activeforeground, anchor,
-        background, bd, bg, bitmap, borderwidth, command, cursor,
-        disabledforeground, fg, font, foreground, height,
-        highlightbackground, highlightcolor, highlightthickness, image,
-        indicatoron, justify, offvalue, onvalue, padx, pady, relief,
-        selectcolor, selectimage, state, takefocus, text, textvariable,
-        underline, variable, width, wraplength."""
-        Widget.__init__(self, master, 'checkbutton', cnf, kw)
-    def deselect(self):
-        """Put the button in off-state."""
-        self.tk.call(self._w, 'deselect')
-    def flash(self):
-        """Flash the button."""
-        self.tk.call(self._w, 'flash')
-    def invoke(self):
-        """Toggle the button and invoke a command if given as resource."""
-        return self.tk.call(self._w, 'invoke')
-    def select(self):
-        """Put the button in on-state."""
-        self.tk.call(self._w, 'select')
-    def toggle(self):
-        """Toggle the button."""
-        self.tk.call(self._w, 'toggle')
-
-class Entry(Widget):
-    """Entry widget which allows to display simple text."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct an entry widget with the parent MASTER.
-
-        Valid resource names: background, bd, bg, borderwidth, cursor,
-        exportselection, fg, font, foreground, highlightbackground,
-        highlightcolor, highlightthickness, insertbackground,
-        insertborderwidth, insertofftime, insertontime, insertwidth,
-        invalidcommand, invcmd, justify, relief, selectbackground,
-        selectborderwidth, selectforeground, show, state, takefocus,
-        textvariable, validate, validatecommand, vcmd, width,
-        xscrollcommand."""
-        Widget.__init__(self, master, 'entry', cnf, kw)
-    def delete(self, first, last=None):
-        """Delete text from FIRST to LAST (not included)."""
-        self.tk.call(self._w, 'delete', first, last)
-    def get(self):
-        """Return the text."""
-        return self.tk.call(self._w, 'get')
-    def icursor(self, index):
-        """Insert cursor at INDEX."""
-        self.tk.call(self._w, 'icursor', index)
-    def index(self, index):
-        """Return position of cursor."""
-        return getint(self.tk.call(
-            self._w, 'index', index))
-    def insert(self, index, string):
-        """Insert STRING at INDEX."""
-        self.tk.call(self._w, 'insert', index, string)
-    def scan_mark(self, x):
-        """Remember the current X, Y coordinates."""
-        self.tk.call(self._w, 'scan', 'mark', x)
-    def scan_dragto(self, x):
-        """Adjust the view of the canvas to 10 times the
-        difference between X and Y and the coordinates given in
-        scan_mark."""
-        self.tk.call(self._w, 'scan', 'dragto', x)
-    def selection_adjust(self, index):
-        """Adjust the end of the selection near the cursor to INDEX."""
-        self.tk.call(self._w, 'selection', 'adjust', index)
-    select_adjust = selection_adjust
-    def selection_clear(self):
-        """Clear the selection if it is in this widget."""
-        self.tk.call(self._w, 'selection', 'clear')
-    select_clear = selection_clear
-    def selection_from(self, index):
-        """Set the fixed end of a selection to INDEX."""
-        self.tk.call(self._w, 'selection', 'from', index)
-    select_from = selection_from
-    def selection_present(self):
-        """Return whether the widget has the selection."""
-        return self.tk.getboolean(
-            self.tk.call(self._w, 'selection', 'present'))
-    select_present = selection_present
-    def selection_range(self, start, end):
-        """Set the selection from START to END (not included)."""
-        self.tk.call(self._w, 'selection', 'range', start, end)
-    select_range = selection_range
-    def selection_to(self, index):
-        """Set the variable end of a selection to INDEX."""
-        self.tk.call(self._w, 'selection', 'to', index)
-    select_to = selection_to
-    def xview(self, index):
-        """Query and change horizontal position of the view."""
-        self.tk.call(self._w, 'xview', index)
-    def xview_moveto(self, fraction):
-        """Adjust the view in the window so that FRACTION of the
-        total width of the entry is off-screen to the left."""
-        self.tk.call(self._w, 'xview', 'moveto', fraction)
-    def xview_scroll(self, number, what):
-        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'xview', 'scroll', number, what)
-
-class Frame(Widget):
-    """Frame widget which may contain other widgets and can have a 3D border."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a frame widget with the parent MASTER.
-
-        Valid resource names: background, bd, bg, borderwidth, class,
-        colormap, container, cursor, height, highlightbackground,
-        highlightcolor, highlightthickness, relief, takefocus, visual, width."""
-        cnf = _cnfmerge((cnf, kw))
-        extra = ()
-        if cnf.has_key('class_'):
-            extra = ('-class', cnf['class_'])
-            del cnf['class_']
-        elif cnf.has_key('class'):
-            extra = ('-class', cnf['class'])
-            del cnf['class']
-        Widget.__init__(self, master, 'frame', cnf, {}, extra)
-
-class Label(Widget):
-    """Label widget which can display text and bitmaps."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a label widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            activebackground, activeforeground, anchor,
-            background, bitmap, borderwidth, cursor,
-            disabledforeground, font, foreground,
-            highlightbackground, highlightcolor,
-            highlightthickness, image, justify,
-            padx, pady, relief, takefocus, text,
-            textvariable, underline, wraplength
-
-        WIDGET-SPECIFIC OPTIONS
-
-            height, state, width
-
-        """
-        Widget.__init__(self, master, 'label', cnf, kw)
-
-class Listbox(Widget):
-    """Listbox widget which can display a list of strings."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a listbox widget with the parent MASTER.
-
-        Valid resource names: background, bd, bg, borderwidth, cursor,
-        exportselection, fg, font, foreground, height, highlightbackground,
-        highlightcolor, highlightthickness, relief, selectbackground,
-        selectborderwidth, selectforeground, selectmode, setgrid, takefocus,
-        width, xscrollcommand, yscrollcommand, listvariable."""
-        Widget.__init__(self, master, 'listbox', cnf, kw)
-    def activate(self, index):
-        """Activate item identified by INDEX."""
-        self.tk.call(self._w, 'activate', index)
-    def bbox(self, *args):
-        """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle
-        which encloses the item identified by index in ARGS."""
-        return self._getints(
-            self.tk.call((self._w, 'bbox') + args)) or None
-    def curselection(self):
-        """Return list of indices of currently selected item."""
-        # XXX Ought to apply self._getints()...
-        return self.tk.splitlist(self.tk.call(
-            self._w, 'curselection'))
-    def delete(self, first, last=None):
-        """Delete items from FIRST to LAST (not included)."""
-        self.tk.call(self._w, 'delete', first, last)
-    def get(self, first, last=None):
-        """Get list of items from FIRST to LAST (not included)."""
-        if last:
-            return self.tk.splitlist(self.tk.call(
-                self._w, 'get', first, last))
-        else:
-            return self.tk.call(self._w, 'get', first)
-    def index(self, index):
-        """Return index of item identified with INDEX."""
-        i = self.tk.call(self._w, 'index', index)
-        if i == 'none': return None
-        return getint(i)
-    def insert(self, index, *elements):
-        """Insert ELEMENTS at INDEX."""
-        self.tk.call((self._w, 'insert', index) + elements)
-    def nearest(self, y):
-        """Get index of item which is nearest to y coordinate Y."""
-        return getint(self.tk.call(
-            self._w, 'nearest', y))
-    def scan_mark(self, x, y):
-        """Remember the current X, Y coordinates."""
-        self.tk.call(self._w, 'scan', 'mark', x, y)
-    def scan_dragto(self, x, y):
-        """Adjust the view of the listbox to 10 times the
-        difference between X and Y and the coordinates given in
-        scan_mark."""
-        self.tk.call(self._w, 'scan', 'dragto', x, y)
-    def see(self, index):
-        """Scroll such that INDEX is visible."""
-        self.tk.call(self._w, 'see', index)
-    def selection_anchor(self, index):
-        """Set the fixed end oft the selection to INDEX."""
-        self.tk.call(self._w, 'selection', 'anchor', index)
-    select_anchor = selection_anchor
-    def selection_clear(self, first, last=None):
-        """Clear the selection from FIRST to LAST (not included)."""
-        self.tk.call(self._w,
-                 'selection', 'clear', first, last)
-    select_clear = selection_clear
-    def selection_includes(self, index):
-        """Return 1 if INDEX is part of the selection."""
-        return self.tk.getboolean(self.tk.call(
-            self._w, 'selection', 'includes', index))
-    select_includes = selection_includes
-    def selection_set(self, first, last=None):
-        """Set the selection from FIRST to LAST (not included) without
-        changing the currently selected elements."""
-        self.tk.call(self._w, 'selection', 'set', first, last)
-    select_set = selection_set
-    def size(self):
-        """Return the number of elements in the listbox."""
-        return getint(self.tk.call(self._w, 'size'))
-    def xview(self, *what):
-        """Query and change horizontal position of the view."""
-        if not what:
-            return self._getdoubles(self.tk.call(self._w, 'xview'))
-        self.tk.call((self._w, 'xview') + what)
-    def xview_moveto(self, fraction):
-        """Adjust the view in the window so that FRACTION of the
-        total width of the entry is off-screen to the left."""
-        self.tk.call(self._w, 'xview', 'moveto', fraction)
-    def xview_scroll(self, number, what):
-        """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'xview', 'scroll', number, what)
-    def yview(self, *what):
-        """Query and change vertical position of the view."""
-        if not what:
-            return self._getdoubles(self.tk.call(self._w, 'yview'))
-        self.tk.call((self._w, 'yview') + what)
-    def yview_moveto(self, fraction):
-        """Adjust the view in the window so that FRACTION of the
-        total width of the entry is off-screen to the top."""
-        self.tk.call(self._w, 'yview', 'moveto', fraction)
-    def yview_scroll(self, number, what):
-        """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'yview', 'scroll', number, what)
-    def itemcget(self, index, option):
-        """Return the resource value for an ITEM and an OPTION."""
-        return self.tk.call(
-            (self._w, 'itemcget') + (index, '-'+option))
-    def itemconfigure(self, index, cnf=None, **kw):
-        """Configure resources of an ITEM.
-
-        The values for resources are specified as keyword arguments.
-        To get an overview about the allowed keyword arguments
-        call the method without arguments.
-        Valid resource names: background, bg, foreground, fg,
-        selectbackground, selectforeground."""
-        return self._configure(('itemconfigure', index), cnf, kw)
-    itemconfig = itemconfigure
-
-class Menu(Widget):
-    """Menu widget which allows to display menu bars, pull-down menus and pop-up menus."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct menu widget with the parent MASTER.
-
-        Valid resource names: activebackground, activeborderwidth,
-        activeforeground, background, bd, bg, borderwidth, cursor,
-        disabledforeground, fg, font, foreground, postcommand, relief,
-        selectcolor, takefocus, tearoff, tearoffcommand, title, type."""
-        Widget.__init__(self, master, 'menu', cnf, kw)
-    def tk_bindForTraversal(self):
-        pass # obsolete since Tk 4.0
-    def tk_mbPost(self):
-        self.tk.call('tk_mbPost', self._w)
-    def tk_mbUnpost(self):
-        self.tk.call('tk_mbUnpost')
-    def tk_traverseToMenu(self, char):
-        self.tk.call('tk_traverseToMenu', self._w, char)
-    def tk_traverseWithinMenu(self, char):
-        self.tk.call('tk_traverseWithinMenu', self._w, char)
-    def tk_getMenuButtons(self):
-        return self.tk.call('tk_getMenuButtons', self._w)
-    def tk_nextMenu(self, count):
-        self.tk.call('tk_nextMenu', count)
-    def tk_nextMenuEntry(self, count):
-        self.tk.call('tk_nextMenuEntry', count)
-    def tk_invokeMenu(self):
-        self.tk.call('tk_invokeMenu', self._w)
-    def tk_firstMenu(self):
-        self.tk.call('tk_firstMenu', self._w)
-    def tk_mbButtonDown(self):
-        self.tk.call('tk_mbButtonDown', self._w)
-    def tk_popup(self, x, y, entry=""):
-        """Post the menu at position X,Y with entry ENTRY."""
-        self.tk.call('tk_popup', self._w, x, y, entry)
-    def activate(self, index):
-        """Activate entry at INDEX."""
-        self.tk.call(self._w, 'activate', index)
-    def add(self, itemType, cnf={}, **kw):
-        """Internal function."""
-        self.tk.call((self._w, 'add', itemType) +
-                 self._options(cnf, kw))
-    def add_cascade(self, cnf={}, **kw):
-        """Add hierarchical menu item."""
-        self.add('cascade', cnf or kw)
-    def add_checkbutton(self, cnf={}, **kw):
-        """Add checkbutton menu item."""
-        self.add('checkbutton', cnf or kw)
-    def add_command(self, cnf={}, **kw):
-        """Add command menu item."""
-        self.add('command', cnf or kw)
-    def add_radiobutton(self, cnf={}, **kw):
-        """Addd radio menu item."""
-        self.add('radiobutton', cnf or kw)
-    def add_separator(self, cnf={}, **kw):
-        """Add separator."""
-        self.add('separator', cnf or kw)
-    def insert(self, index, itemType, cnf={}, **kw):
-        """Internal function."""
-        self.tk.call((self._w, 'insert', index, itemType) +
-                 self._options(cnf, kw))
-    def insert_cascade(self, index, cnf={}, **kw):
-        """Add hierarchical menu item at INDEX."""
-        self.insert(index, 'cascade', cnf or kw)
-    def insert_checkbutton(self, index, cnf={}, **kw):
-        """Add checkbutton menu item at INDEX."""
-        self.insert(index, 'checkbutton', cnf or kw)
-    def insert_command(self, index, cnf={}, **kw):
-        """Add command menu item at INDEX."""
-        self.insert(index, 'command', cnf or kw)
-    def insert_radiobutton(self, index, cnf={}, **kw):
-        """Addd radio menu item at INDEX."""
-        self.insert(index, 'radiobutton', cnf or kw)
-    def insert_separator(self, index, cnf={}, **kw):
-        """Add separator at INDEX."""
-        self.insert(index, 'separator', cnf or kw)
-    def delete(self, index1, index2=None):
-        """Delete menu items between INDEX1 and INDEX2 (not included)."""
-        self.tk.call(self._w, 'delete', index1, index2)
-    def entrycget(self, index, option):
-        """Return the resource value of an menu item for OPTION at INDEX."""
-        return self.tk.call(self._w, 'entrycget', index, '-' + option)
-    def entryconfigure(self, index, cnf=None, **kw):
-        """Configure a menu item at INDEX."""
-        return self._configure(('entryconfigure', index), cnf, kw)
-    entryconfig = entryconfigure
-    def index(self, index):
-        """Return the index of a menu item identified by INDEX."""
-        i = self.tk.call(self._w, 'index', index)
-        if i == 'none': return None
-        return getint(i)
-    def invoke(self, index):
-        """Invoke a menu item identified by INDEX and execute
-        the associated command."""
-        return self.tk.call(self._w, 'invoke', index)
-    def post(self, x, y):
-        """Display a menu at position X,Y."""
-        self.tk.call(self._w, 'post', x, y)
-    def type(self, index):
-        """Return the type of the menu item at INDEX."""
-        return self.tk.call(self._w, 'type', index)
-    def unpost(self):
-        """Unmap a menu."""
-        self.tk.call(self._w, 'unpost')
-    def yposition(self, index):
-        """Return the y-position of the topmost pixel of the menu item at INDEX."""
-        return getint(self.tk.call(
-            self._w, 'yposition', index))
-
-class Menubutton(Widget):
-    """Menubutton widget, obsolete since Tk8.0."""
-    def __init__(self, master=None, cnf={}, **kw):
-        Widget.__init__(self, master, 'menubutton', cnf, kw)
-
-class Message(Widget):
-    """Message widget to display multiline text. Obsolete since Label does it too."""
-    def __init__(self, master=None, cnf={}, **kw):
-        Widget.__init__(self, master, 'message', cnf, kw)
-
-class Radiobutton(Widget):
-    """Radiobutton widget which shows only one of several buttons in on-state."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a radiobutton widget with the parent MASTER.
-
-        Valid resource names: activebackground, activeforeground, anchor,
-        background, bd, bg, bitmap, borderwidth, command, cursor,
-        disabledforeground, fg, font, foreground, height,
-        highlightbackground, highlightcolor, highlightthickness, image,
-        indicatoron, justify, padx, pady, relief, selectcolor, selectimage,
-        state, takefocus, text, textvariable, underline, value, variable,
-        width, wraplength."""
-        Widget.__init__(self, master, 'radiobutton', cnf, kw)
-    def deselect(self):
-        """Put the button in off-state."""
-
-        self.tk.call(self._w, 'deselect')
-    def flash(self):
-        """Flash the button."""
-        self.tk.call(self._w, 'flash')
-    def invoke(self):
-        """Toggle the button and invoke a command if given as resource."""
-        return self.tk.call(self._w, 'invoke')
-    def select(self):
-        """Put the button in on-state."""
-        self.tk.call(self._w, 'select')
-
-class Scale(Widget):
-    """Scale widget which can display a numerical scale."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a scale widget with the parent MASTER.
-
-        Valid resource names: activebackground, background, bigincrement, bd,
-        bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
-        highlightbackground, highlightcolor, highlightthickness, label,
-        length, orient, relief, repeatdelay, repeatinterval, resolution,
-        showvalue, sliderlength, sliderrelief, state, takefocus,
-        tickinterval, to, troughcolor, variable, width."""
-        Widget.__init__(self, master, 'scale', cnf, kw)
-    def get(self):
-        """Get the current value as integer or float."""
-        value = self.tk.call(self._w, 'get')
-        try:
-            return getint(value)
-        except ValueError:
-            return getdouble(value)
-    def set(self, value):
-        """Set the value to VALUE."""
-        self.tk.call(self._w, 'set', value)
-    def coords(self, value=None):
-        """Return a tuple (X,Y) of the point along the centerline of the
-        trough that corresponds to VALUE or the current value if None is
-        given."""
-
-        return self._getints(self.tk.call(self._w, 'coords', value))
-    def identify(self, x, y):
-        """Return where the point X,Y lies. Valid return values are "slider",
-        "though1" and "though2"."""
-        return self.tk.call(self._w, 'identify', x, y)
-
-class Scrollbar(Widget):
-    """Scrollbar widget which displays a slider at a certain position."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a scrollbar widget with the parent MASTER.
-
-        Valid resource names: activebackground, activerelief,
-        background, bd, bg, borderwidth, command, cursor,
-        elementborderwidth, highlightbackground,
-        highlightcolor, highlightthickness, jump, orient,
-        relief, repeatdelay, repeatinterval, takefocus,
-        troughcolor, width."""
-        Widget.__init__(self, master, 'scrollbar', cnf, kw)
-    def activate(self, index):
-        """Display the element at INDEX with activebackground and activerelief.
-        INDEX can be "arrow1","slider" or "arrow2"."""
-        self.tk.call(self._w, 'activate', index)
-    def delta(self, deltax, deltay):
-        """Return the fractional change of the scrollbar setting if it
-        would be moved by DELTAX or DELTAY pixels."""
-        return getdouble(
-            self.tk.call(self._w, 'delta', deltax, deltay))
-    def fraction(self, x, y):
-        """Return the fractional value which corresponds to a slider
-        position of X,Y."""
-        return getdouble(self.tk.call(self._w, 'fraction', x, y))
-    def identify(self, x, y):
-        """Return the element under position X,Y as one of
-        "arrow1","slider","arrow2" or ""."""
-        return self.tk.call(self._w, 'identify', x, y)
-    def get(self):
-        """Return the current fractional values (upper and lower end)
-        of the slider position."""
-        return self._getdoubles(self.tk.call(self._w, 'get'))
-    def set(self, *args):
-        """Set the fractional values of the slider position (upper and
-        lower ends as value between 0 and 1)."""
-        self.tk.call((self._w, 'set') + args)
-
-
-
-class Text(Widget):
-    """Text widget which can display text in various forms."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a text widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            background, borderwidth, cursor,
-            exportselection, font, foreground,
-            highlightbackground, highlightcolor,
-            highlightthickness, insertbackground,
-            insertborderwidth, insertofftime,
-            insertontime, insertwidth, padx, pady,
-            relief, selectbackground,
-            selectborderwidth, selectforeground,
-            setgrid, takefocus,
-            xscrollcommand, yscrollcommand,
-
-        WIDGET-SPECIFIC OPTIONS
-
-            autoseparators, height, maxundo,
-            spacing1, spacing2, spacing3,
-            state, tabs, undo, width, wrap,
-
-        """
-        Widget.__init__(self, master, 'text', cnf, kw)
-    def bbox(self, *args):
-        """Return a tuple of (x,y,width,height) which gives the bounding
-        box of the visible part of the character at the index in ARGS."""
-        return self._getints(
-            self.tk.call((self._w, 'bbox') + args)) or None
-    def tk_textSelectTo(self, index):
-        self.tk.call('tk_textSelectTo', self._w, index)
-    def tk_textBackspace(self):
-        self.tk.call('tk_textBackspace', self._w)
-    def tk_textIndexCloser(self, a, b, c):
-        self.tk.call('tk_textIndexCloser', self._w, a, b, c)
-    def tk_textResetAnchor(self, index):
-        self.tk.call('tk_textResetAnchor', self._w, index)
-    def compare(self, index1, op, index2):
-        """Return whether between index INDEX1 and index INDEX2 the
-        relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=."""
-        return self.tk.getboolean(self.tk.call(
-            self._w, 'compare', index1, op, index2))
-    def debug(self, boolean=None):
-        """Turn on the internal consistency checks of the B-Tree inside the text
-        widget according to BOOLEAN."""
-        return self.tk.getboolean(self.tk.call(
-            self._w, 'debug', boolean))
-    def delete(self, index1, index2=None):
-        """Delete the characters between INDEX1 and INDEX2 (not included)."""
-        self.tk.call(self._w, 'delete', index1, index2)
-    def dlineinfo(self, index):
-        """Return tuple (x,y,width,height,baseline) giving the bounding box
-        and baseline position of the visible part of the line containing
-        the character at INDEX."""
-        return self._getints(self.tk.call(self._w, 'dlineinfo', index))
-    def dump(self, index1, index2=None, command=None, **kw):
-        """Return the contents of the widget between index1 and index2.
-
-        The type of contents returned in filtered based on the keyword
-        parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are
-        given and true, then the corresponding items are returned. The result
-        is a list of triples of the form (key, value, index). If none of the
-        keywords are true then 'all' is used by default.
-
-        If the 'command' argument is given, it is called once for each element
-        of the list of triples, with the values of each triple serving as the
-        arguments to the function. In this case the list is not returned."""
-        args = []
-        func_name = None
-        result = None
-        if not command:
-            # Never call the dump command without the -command flag, since the
-            # output could involve Tcl quoting and would be a pain to parse
-            # right. Instead just set the command to build a list of triples
-            # as if we had done the parsing.
-            result = []
-            def append_triple(key, value, index, result=result):
-                result.append((key, value, index))
-            command = append_triple
-        try:
-            if not isinstance(command, str):
-                func_name = command = self._register(command)
-            args += ["-command", command]
-            for key in kw:
-                if kw[key]: args.append("-" + key)
-            args.append(index1)
-            if index2:
-                args.append(index2)
-            self.tk.call(self._w, "dump", *args)
-            return result
-        finally:
-            if func_name:
-                self.deletecommand(func_name)
-
-    ## new in tk8.4
-    def edit(self, *args):
-        """Internal method
-
-        This method controls the undo mechanism and
-        the modified flag. The exact behavior of the
-        command depends on the option argument that
-        follows the edit argument. The following forms
-        of the command are currently supported:
-
-        edit_modified, edit_redo, edit_reset, edit_separator
-        and edit_undo
-
-        """
-        return self.tk.call(self._w, 'edit', *args)
-
-    def edit_modified(self, arg=None):
-        """Get or Set the modified flag
-
-        If arg is not specified, returns the modified
-        flag of the widget. The insert, delete, edit undo and
-        edit redo commands or the user can set or clear the
-        modified flag. If boolean is specified, sets the
-        modified flag of the widget to arg.
-        """
-        return self.edit("modified", arg)
-
-    def edit_redo(self):
-        """Redo the last undone edit
-
-        When the undo option is true, reapplies the last
-        undone edits provided no other edits were done since
-        then. Generates an error when the redo stack is empty.
-        Does nothing when the undo option is false.
-        """
-        return self.edit("redo")
-
-    def edit_reset(self):
-        """Clears the undo and redo stacks
-        """
-        return self.edit("reset")
-
-    def edit_separator(self):
-        """Inserts a separator (boundary) on the undo stack.
-
-        Does nothing when the undo option is false
-        """
-        return self.edit("separator")
-
-    def edit_undo(self):
-        """Undoes the last edit action
-
-        If the undo option is true. An edit action is defined
-        as all the insert and delete commands that are recorded
-        on the undo stack in between two separators. Generates
-        an error when the undo stack is empty. Does nothing
-        when the undo option is false
-        """
-        return self.edit("undo")
-
-    def get(self, index1, index2=None):
-        """Return the text from INDEX1 to INDEX2 (not included)."""
-        return self.tk.call(self._w, 'get', index1, index2)
-    # (Image commands are new in 8.0)
-    def image_cget(self, index, option):
-        """Return the value of OPTION of an embedded image at INDEX."""
-        if option[:1] != "-":
-            option = "-" + option
-        if option[-1:] == "_":
-            option = option[:-1]
-        return self.tk.call(self._w, "image", "cget", index, option)
-    def image_configure(self, index, cnf=None, **kw):
-        """Configure an embedded image at INDEX."""
-        return self._configure(('image', 'configure', index), cnf, kw)
-    def image_create(self, index, cnf={}, **kw):
-        """Create an embedded image at INDEX."""
-        return self.tk.call(
-                 self._w, "image", "create", index,
-                 *self._options(cnf, kw))
-    def image_names(self):
-        """Return all names of embedded images in this widget."""
-        return self.tk.call(self._w, "image", "names")
-    def index(self, index):
-        """Return the index in the form line.char for INDEX."""
-        return str(self.tk.call(self._w, 'index', index))
-    def insert(self, index, chars, *args):
-        """Insert CHARS before the characters at INDEX. An additional
-        tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
-        self.tk.call((self._w, 'insert', index, chars) + args)
-    def mark_gravity(self, markName, direction=None):
-        """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT).
-        Return the current value if None is given for DIRECTION."""
-        return self.tk.call(
-            (self._w, 'mark', 'gravity', markName, direction))
-    def mark_names(self):
-        """Return all mark names."""
-        return self.tk.splitlist(self.tk.call(
-            self._w, 'mark', 'names'))
-    def mark_set(self, markName, index):
-        """Set mark MARKNAME before the character at INDEX."""
-        self.tk.call(self._w, 'mark', 'set', markName, index)
-    def mark_unset(self, *markNames):
-        """Delete all marks in MARKNAMES."""
-        self.tk.call((self._w, 'mark', 'unset') + markNames)
-    def mark_next(self, index):
-        """Return the name of the next mark after INDEX."""
-        return self.tk.call(self._w, 'mark', 'next', index) or None
-    def mark_previous(self, index):
-        """Return the name of the previous mark before INDEX."""
-        return self.tk.call(self._w, 'mark', 'previous', index) or None
-    def scan_mark(self, x, y):
-        """Remember the current X, Y coordinates."""
-        self.tk.call(self._w, 'scan', 'mark', x, y)
-    def scan_dragto(self, x, y):
-        """Adjust the view of the text to 10 times the
-        difference between X and Y and the coordinates given in
-        scan_mark."""
-        self.tk.call(self._w, 'scan', 'dragto', x, y)
-    def search(self, pattern, index, stopindex=None,
-           forwards=None, backwards=None, exact=None,
-           regexp=None, nocase=None, count=None, elide=None):
-        """Search PATTERN beginning from INDEX until STOPINDEX.
-        Return the index of the first character of a match or an empty string."""
-        args = [self._w, 'search']
-        if forwards: args.append('-forwards')
-        if backwards: args.append('-backwards')
-        if exact: args.append('-exact')
-        if regexp: args.append('-regexp')
-        if nocase: args.append('-nocase')
-        if elide: args.append('-elide')
-        if count: args.append('-count'); args.append(count)
-        if pattern[0] == '-': args.append('--')
-        args.append(pattern)
-        args.append(index)
-        if stopindex: args.append(stopindex)
-        return self.tk.call(tuple(args))
-    def see(self, index):
-        """Scroll such that the character at INDEX is visible."""
-        self.tk.call(self._w, 'see', index)
-    def tag_add(self, tagName, index1, *args):
-        """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS.
-        Additional pairs of indices may follow in ARGS."""
-        self.tk.call(
-            (self._w, 'tag', 'add', tagName, index1) + args)
-    def tag_unbind(self, tagName, sequence, funcid=None):
-        """Unbind for all characters with TAGNAME for event SEQUENCE  the
-        function identified with FUNCID."""
-        self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
-        if funcid:
-            self.deletecommand(funcid)
-    def tag_bind(self, tagName, sequence, func, add=None):
-        """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
-
-        An additional boolean parameter ADD specifies whether FUNC will be
-        called additionally to the other bound function or whether it will
-        replace the previous function. See bind for the return value."""
-        return self._bind((self._w, 'tag', 'bind', tagName),
-                  sequence, func, add)
-    def tag_cget(self, tagName, option):
-        """Return the value of OPTION for tag TAGNAME."""
-        if option[:1] != '-':
-            option = '-' + option
-        if option[-1:] == '_':
-            option = option[:-1]
-        return self.tk.call(self._w, 'tag', 'cget', tagName, option)
-    def tag_configure(self, tagName, cnf=None, **kw):
-        """Configure a tag TAGNAME."""
-        return self._configure(('tag', 'configure', tagName), cnf, kw)
-    tag_config = tag_configure
-    def tag_delete(self, *tagNames):
-        """Delete all tags in TAGNAMES."""
-        self.tk.call((self._w, 'tag', 'delete') + tagNames)
-    def tag_lower(self, tagName, belowThis=None):
-        """Change the priority of tag TAGNAME such that it is lower
-        than the priority of BELOWTHIS."""
-        self.tk.call(self._w, 'tag', 'lower', tagName, belowThis)
-    def tag_names(self, index=None):
-        """Return a list of all tag names."""
-        return self.tk.splitlist(
-            self.tk.call(self._w, 'tag', 'names', index))
-    def tag_nextrange(self, tagName, index1, index2=None):
-        """Return a list of start and end index for the first sequence of
-        characters between INDEX1 and INDEX2 which all have tag TAGNAME.
-        The text is searched forward from INDEX1."""
-        return self.tk.splitlist(self.tk.call(
-            self._w, 'tag', 'nextrange', tagName, index1, index2))
-    def tag_prevrange(self, tagName, index1, index2=None):
-        """Return a list of start and end index for the first sequence of
-        characters between INDEX1 and INDEX2 which all have tag TAGNAME.
-        The text is searched backwards from INDEX1."""
-        return self.tk.splitlist(self.tk.call(
-            self._w, 'tag', 'prevrange', tagName, index1, index2))
-    def tag_raise(self, tagName, aboveThis=None):
-        """Change the priority of tag TAGNAME such that it is higher
-        than the priority of ABOVETHIS."""
-        self.tk.call(
-            self._w, 'tag', 'raise', tagName, aboveThis)
-    def tag_ranges(self, tagName):
-        """Return a list of ranges of text which have tag TAGNAME."""
-        return self.tk.splitlist(self.tk.call(
-            self._w, 'tag', 'ranges', tagName))
-    def tag_remove(self, tagName, index1, index2=None):
-        """Remove tag TAGNAME from all characters between INDEX1 and INDEX2."""
-        self.tk.call(
-            self._w, 'tag', 'remove', tagName, index1, index2)
-    def window_cget(self, index, option):
-        """Return the value of OPTION of an embedded window at INDEX."""
-        if option[:1] != '-':
-            option = '-' + option
-        if option[-1:] == '_':
-            option = option[:-1]
-        return self.tk.call(self._w, 'window', 'cget', index, option)
-    def window_configure(self, index, cnf=None, **kw):
-        """Configure an embedded window at INDEX."""
-        return self._configure(('window', 'configure', index), cnf, kw)
-    window_config = window_configure
-    def window_create(self, index, cnf={}, **kw):
-        """Create a window at INDEX."""
-        self.tk.call(
-              (self._w, 'window', 'create', index)
-              + self._options(cnf, kw))
-    def window_names(self):
-        """Return all names of embedded windows in this widget."""
-        return self.tk.splitlist(
-            self.tk.call(self._w, 'window', 'names'))
-    def xview(self, *what):
-        """Query and change horizontal position of the view."""
-        if not what:
-            return self._getdoubles(self.tk.call(self._w, 'xview'))
-        self.tk.call((self._w, 'xview') + what)
-    def xview_moveto(self, fraction):
-        """Adjusts the view in the window so that FRACTION of the
-        total width of the canvas is off-screen to the left."""
-        self.tk.call(self._w, 'xview', 'moveto', fraction)
-    def xview_scroll(self, number, what):
-        """Shift the x-view according to NUMBER which is measured
-        in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'xview', 'scroll', number, what)
-    def yview(self, *what):
-        """Query and change vertical position of the view."""
-        if not what:
-            return self._getdoubles(self.tk.call(self._w, 'yview'))
-        self.tk.call((self._w, 'yview') + what)
-    def yview_moveto(self, fraction):
-        """Adjusts the view in the window so that FRACTION of the
-        total height of the canvas is off-screen to the top."""
-        self.tk.call(self._w, 'yview', 'moveto', fraction)
-    def yview_scroll(self, number, what):
-        """Shift the y-view according to NUMBER which is measured
-        in "units" or "pages" (WHAT)."""
-        self.tk.call(self._w, 'yview', 'scroll', number, what)
-    def yview_pickplace(self, *what):
-        """Obsolete function, use see."""
-        self.tk.call((self._w, 'yview', '-pickplace') + what)
-
-
-class _setit:
-    """Internal class. It wraps the command in the widget OptionMenu."""
-    def __init__(self, var, value, callback=None):
-        self.__value = value
-        self.__var = var
-        self.__callback = callback
-    def __call__(self, *args):
-        self.__var.set(self.__value)
-        if self.__callback:
-            self.__callback(self.__value, *args)
-
-class OptionMenu(Menubutton):
-    """OptionMenu which allows the user to select a value from a menu."""
-    def __init__(self, master, variable, value, *values, **kwargs):
-        """Construct an optionmenu widget with the parent MASTER, with
-        the resource textvariable set to VARIABLE, the initially selected
-        value VALUE, the other menu values VALUES and an additional
-        keyword argument command."""
-        kw = {"borderwidth": 2, "textvariable": variable,
-              "indicatoron": 1, "relief": RAISED, "anchor": "c",
-              "highlightthickness": 2}
-        Widget.__init__(self, master, "menubutton", kw)
-        self.widgetName = 'tk_optionMenu'
-        menu = self.__menu = Menu(self, name="menu", tearoff=0)
-        self.menuname = menu._w
-        # 'command' is the only supported keyword
-        callback = kwargs.get('command')
-        if kwargs.has_key('command'):
-            del kwargs['command']
-        if kwargs:
-            raise TclError, 'unknown option -'+kwargs.keys()[0]
-        menu.add_command(label=value,
-                 command=_setit(variable, value, callback))
-        for v in values:
-            menu.add_command(label=v,
-                     command=_setit(variable, v, callback))
-        self["menu"] = menu
-
-    def __getitem__(self, name):
-        if name == 'menu':
-            return self.__menu
-        return Widget.__getitem__(self, name)
-
-    def destroy(self):
-        """Destroy this widget and the associated menu."""
-        Menubutton.destroy(self)
-        self.__menu = None
-
-class Image:
-    """Base class for images."""
-    _last_id = 0
-    def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
-        self.name = None
-        if not master:
-            master = _default_root
-            if not master:
-                raise RuntimeError, 'Too early to create image'
-        self.tk = master.tk
-        if not name:
-            Image._last_id += 1
-            name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x>
-            # The following is needed for systems where id(x)
-            # can return a negative number, such as Linux/m68k:
-            if name[0] == '-': name = '_' + name[1:]
-        if kw and cnf: cnf = _cnfmerge((cnf, kw))
-        elif kw: cnf = kw
-        options = ()
-        for k, v in cnf.items():
-            if callable(v):
-                v = self._register(v)
-            options = options + ('-'+k, v)
-        self.tk.call(('image', 'create', imgtype, name,) + options)
-        self.name = name
-    def __str__(self): return self.name
-    def __del__(self):
-        if self.name:
-            try:
-                self.tk.call('image', 'delete', self.name)
-            except TclError:
-                # May happen if the root was destroyed
-                pass
-    def __setitem__(self, key, value):
-        self.tk.call(self.name, 'configure', '-'+key, value)
-    def __getitem__(self, key):
-        return self.tk.call(self.name, 'configure', '-'+key)
-    def configure(self, **kw):
-        """Configure the image."""
-        res = ()
-        for k, v in _cnfmerge(kw).items():
-            if v is not None:
-                if k[-1] == '_': k = k[:-1]
-                if callable(v):
-                    v = self._register(v)
-                res = res + ('-'+k, v)
-        self.tk.call((self.name, 'config') + res)
-    config = configure
-    def height(self):
-        """Return the height of the image."""
-        return getint(
-            self.tk.call('image', 'height', self.name))
-    def type(self):
-        """Return the type of the imgage, e.g. "photo" or "bitmap"."""
-        return self.tk.call('image', 'type', self.name)
-    def width(self):
-        """Return the width of the image."""
-        return getint(
-            self.tk.call('image', 'width', self.name))
-
-class PhotoImage(Image):
-    """Widget which can display colored images in GIF, PPM/PGM format."""
-    def __init__(self, name=None, cnf={}, master=None, **kw):
-        """Create an image with NAME.
-
-        Valid resource names: data, format, file, gamma, height, palette,
-        width."""
-        Image.__init__(self, 'photo', name, cnf, master, **kw)
-    def blank(self):
-        """Display a transparent image."""
-        self.tk.call(self.name, 'blank')
-    def cget(self, option):
-        """Return the value of OPTION."""
-        return self.tk.call(self.name, 'cget', '-' + option)
-    # XXX config
-    def __getitem__(self, key):
-        return self.tk.call(self.name, 'cget', '-' + key)
-    # XXX copy -from, -to, ...?
-    def copy(self):
-        """Return a new PhotoImage with the same image as this widget."""
-        destImage = PhotoImage()
-        self.tk.call(destImage, 'copy', self.name)
-        return destImage
-    def zoom(self,x,y=''):
-        """Return a new PhotoImage with the same image as this widget
-        but zoom it with X and Y."""
-        destImage = PhotoImage()
-        if y=='': y=x
-        self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
-        return destImage
-    def subsample(self,x,y=''):
-        """Return a new PhotoImage based on the same image as this widget
-        but use only every Xth or Yth pixel."""
-        destImage = PhotoImage()
-        if y=='': y=x
-        self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
-        return destImage
-    def get(self, x, y):
-        """Return the color (red, green, blue) of the pixel at X,Y."""
-        return self.tk.call(self.name, 'get', x, y)
-    def put(self, data, to=None):
-        """Put row formated colors to image starting from
-        position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
-        args = (self.name, 'put', data)
-        if to:
-            if to[0] == '-to':
-                to = to[1:]
-            args = args + ('-to',) + tuple(to)
-        self.tk.call(args)
-    # XXX read
-    def write(self, filename, format=None, from_coords=None):
-        """Write image to file FILENAME in FORMAT starting from
-        position FROM_COORDS."""
-        args = (self.name, 'write', filename)
-        if format:
-            args = args + ('-format', format)
-        if from_coords:
-            args = args + ('-from',) + tuple(from_coords)
-        self.tk.call(args)
-
-class BitmapImage(Image):
-    """Widget which can display a bitmap."""
-    def __init__(self, name=None, cnf={}, master=None, **kw):
-        """Create a bitmap with NAME.
-
-        Valid resource names: background, data, file, foreground, maskdata, maskfile."""
-        Image.__init__(self, 'bitmap', name, cnf, master, **kw)
-
-def image_names(): return _default_root.tk.call('image', 'names')
-def image_types(): return _default_root.tk.call('image', 'types')
-
-
-class Spinbox(Widget):
-    """spinbox widget."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a spinbox widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            activebackground, background, borderwidth,
-            cursor, exportselection, font, foreground,
-            highlightbackground, highlightcolor,
-            highlightthickness, insertbackground,
-            insertborderwidth, insertofftime,
-            insertontime, insertwidth, justify, relief,
-            repeatdelay, repeatinterval,
-            selectbackground, selectborderwidth
-            selectforeground, takefocus, textvariable
-            xscrollcommand.
-
-        WIDGET-SPECIFIC OPTIONS
-
-            buttonbackground, buttoncursor,
-            buttondownrelief, buttonuprelief,
-            command, disabledbackground,
-            disabledforeground, format, from,
-            invalidcommand, increment,
-            readonlybackground, state, to,
-            validate, validatecommand values,
-            width, wrap,
-        """
-        Widget.__init__(self, master, 'spinbox', cnf, kw)
-
-    def bbox(self, index):
-        """Return a tuple of X1,Y1,X2,Y2 coordinates for a
-        rectangle which encloses the character given by index.
-
-        The first two elements of the list give the x and y
-        coordinates of the upper-left corner of the screen
-        area covered by the character (in pixels relative
-        to the widget) and the last two elements give the
-        width and height of the character, in pixels. The
-        bounding box may refer to a region outside the
-        visible area of the window.
-        """
-        return self.tk.call(self._w, 'bbox', index)
-
-    def delete(self, first, last=None):
-        """Delete one or more elements of the spinbox.
-
-        First is the index of the first character to delete,
-        and last is the index of the character just after
-        the last one to delete. If last isn't specified it
-        defaults to first+1, i.e. a single character is
-        deleted.  This command returns an empty string.
-        """
-        return self.tk.call(self._w, 'delete', first, last)
-
-    def get(self):
-        """Returns the spinbox's string"""
-        return self.tk.call(self._w, 'get')
-
-    def icursor(self, index):
-        """Alter the position of the insertion cursor.
-
-        The insertion cursor will be displayed just before
-        the character given by index. Returns an empty string
-        """
-        return self.tk.call(self._w, 'icursor', index)
-
-    def identify(self, x, y):
-        """Returns the name of the widget at position x, y
-
-        Return value is one of: none, buttondown, buttonup, entry
-        """
-        return self.tk.call(self._w, 'identify', x, y)
-
-    def index(self, index):
-        """Returns the numerical index corresponding to index
-        """
-        return self.tk.call(self._w, 'index', index)
-
-    def insert(self, index, s):
-        """Insert string s at index
-
-         Returns an empty string.
-        """
-        return self.tk.call(self._w, 'insert', index, s)
-
-    def invoke(self, element):
-        """Causes the specified element to be invoked
-
-        The element could be buttondown or buttonup
-        triggering the action associated with it.
-        """
-        return self.tk.call(self._w, 'invoke', element)
-
-    def scan(self, *args):
-        """Internal function."""
-        return self._getints(
-            self.tk.call((self._w, 'scan') + args)) or ()
-
-    def scan_mark(self, x):
-        """Records x and the current view in the spinbox window;
-
-        used in conjunction with later scan dragto commands.
-        Typically this command is associated with a mouse button
-        press in the widget. It returns an empty string.
-        """
-        return self.scan("mark", x)
-
-    def scan_dragto(self, x):
-        """Compute the difference between the given x argument
-        and the x argument to the last scan mark command
-
-        It then adjusts the view left or right by 10 times the
-        difference in x-coordinates. This command is typically
-        associated with mouse motion events in the widget, to
-        produce the effect of dragging the spinbox at high speed
-        through the window. The return value is an empty string.
-        """
-        return self.scan("dragto", x)
-
-    def selection(self, *args):
-        """Internal function."""
-        return self._getints(
-            self.tk.call((self._w, 'selection') + args)) or ()
-
-    def selection_adjust(self, index):
-        """Locate the end of the selection nearest to the character
-        given by index,
-
-        Then adjust that end of the selection to be at index
-        (i.e including but not going beyond index). The other
-        end of the selection is made the anchor point for future
-        select to commands. If the selection isn't currently in
-        the spinbox, then a new selection is created to include
-        the characters between index and the most recent selection
-        anchor point, inclusive. Returns an empty string.
-        """
-        return self.selection("adjust", index)
-
-    def selection_clear(self):
-        """Clear the selection
-
-        If the selection isn't in this widget then the
-        command has no effect. Returns an empty string.
-        """
-        return self.selection("clear")
-
-    def selection_element(self, element=None):
-        """Sets or gets the currently selected element.
-
-        If a spinbutton element is specified, it will be
-        displayed depressed
-        """
-        return self.selection("element", element)
-
-###########################################################################
-
-class LabelFrame(Widget):
-    """labelframe widget."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a labelframe widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            borderwidth, cursor, font, foreground,
-            highlightbackground, highlightcolor,
-            highlightthickness, padx, pady, relief,
-            takefocus, text
-
-        WIDGET-SPECIFIC OPTIONS
-
-            background, class, colormap, container,
-            height, labelanchor, labelwidget,
-            visual, width
-        """
-        Widget.__init__(self, master, 'labelframe', cnf, kw)
-
-########################################################################
-
-class PanedWindow(Widget):
-    """panedwindow widget."""
-    def __init__(self, master=None, cnf={}, **kw):
-        """Construct a panedwindow widget with the parent MASTER.
-
-        STANDARD OPTIONS
-
-            background, borderwidth, cursor, height,
-            orient, relief, width
-
-        WIDGET-SPECIFIC OPTIONS
-
-            handlepad, handlesize, opaqueresize,
-            sashcursor, sashpad, sashrelief,
-            sashwidth, showhandle,
-        """
-        Widget.__init__(self, master, 'panedwindow', cnf, kw)
-
-    def add(self, child, **kw):
-        """Add a child widget to the panedwindow in a new pane.
-
-        The child argument is the name of the child widget
-        followed by pairs of arguments that specify how to
-        manage the windows. Options may have any of the values
-        accepted by the configure subcommand.
-        """
-        self.tk.call((self._w, 'add', child) + self._options(kw))
-
-    def remove(self, child):
-        """Remove the pane containing child from the panedwindow
-
-        All geometry management options for child will be forgotten.
-        """
-        self.tk.call(self._w, 'forget', child)
-    forget=remove
-
-    def identify(self, x, y):
-        """Identify the panedwindow component at point x, y
-
-        If the point is over a sash or a sash handle, the result
-        is a two element list containing the index of the sash or
-        handle, and a word indicating whether it is over a sash
-        or a handle, such as {0 sash} or {2 handle}. If the point
-        is over any other part of the panedwindow, the result is
-        an empty list.
-        """
-        return self.tk.call(self._w, 'identify', x, y)
-
-    def proxy(self, *args):
-        """Internal function."""
-        return self._getints(
-            self.tk.call((self._w, 'proxy') + args)) or ()
-
-    def proxy_coord(self):
-        """Return the x and y pair of the most recent proxy location
-        """
-        return self.proxy("coord")
-
-    def proxy_forget(self):
-        """Remove the proxy from the display.
-        """
-        return self.proxy("forget")
-
-    def proxy_place(self, x, y):
-        """Place the proxy at the given x and y coordinates.
-        """
-        return self.proxy("place", x, y)
-
-    def sash(self, *args):
-        """Internal function."""
-        return self._getints(
-            self.tk.call((self._w, 'sash') + args)) or ()
-
-    def sash_coord(self, index):
-        """Return the current x and y pair for the sash given by index.
-
-        Index must be an integer between 0 and 1 less than the
-        number of panes in the panedwindow. The coordinates given are
-        those of the top left corner of the region containing the sash.
-        pathName sash dragto index x y This command computes the
-        difference between the given coordinates and the coordinates
-        given to the last sash coord command for the given sash. It then
-        moves that sash the computed difference. The return value is the
-        empty string.
-        """
-        return self.sash("coord", index)
-
-    def sash_mark(self, index):
-        """Records x and y for the sash given by index;
-
-        Used in conjunction with later dragto commands to move the sash.
-        """
-        return self.sash("mark", index)
-
-    def sash_place(self, index, x, y):
-        """Place the sash given by index at the given coordinates
-        """
-        return self.sash("place", index, x, y)
-
-    def panecget(self, child, option):
-        """Query a management option for window.
-
-        Option may be any value allowed by the paneconfigure subcommand
-        """
-        return self.tk.call(
-            (self._w, 'panecget') + (child, '-'+option))
-
-    def paneconfigure(self, tagOrId, cnf=None, **kw):
-        """Query or modify the management options for window.
-
-        If no option is specified, returns a list describing all
-        of the available options for pathName.  If option is
-        specified with no value, then the command returns a list
-        describing the one named option (this list will be identical
-        to the corresponding sublist of the value returned if no
-        option is specified). If one or more option-value pairs are
-        specified, then the command modifies the given widget
-        option(s) to have the given value(s); in this case the
-        command returns an empty string. The following options
-        are supported:
-
-        after window
-            Insert the window after the window specified. window
-            should be the name of a window already managed by pathName.
-        before window
-            Insert the window before the window specified. window
-            should be the name of a window already managed by pathName.
-        height size
-            Specify a height for the window. The height will be the
-            outer dimension of the window including its border, if
-            any. If size is an empty string, or if -height is not
-            specified, then the height requested internally by the
-            window will be used initially; the height may later be
-            adjusted by the movement of sashes in the panedwindow.
-            Size may be any value accepted by Tk_GetPixels.
-        minsize n
-            Specifies that the size of the window cannot be made
-            less than n. This constraint only affects the size of
-            the widget in the paned dimension -- the x dimension
-            for horizontal panedwindows, the y dimension for
-            vertical panedwindows. May be any value accepted by
-            Tk_GetPixels.
-        padx n
-            Specifies a non-negative value indicating how much
-            extra space to leave on each side of the window in
-            the X-direction. The value may have any of the forms
-            accepted by Tk_GetPixels.
-        pady n
-            Specifies a non-negative value indicating how much
-            extra space to leave on each side of the window in
-            the Y-direction. The value may have any of the forms
-            accepted by Tk_GetPixels.
-        sticky style
-            If a window's pane is larger than the requested
-            dimensions of the window, this option may be used
-            to position (or stretch) the window within its pane.
-            Style is a string that contains zero or more of the
-            characters n, s, e or w. The string can optionally
-            contains spaces or commas, but they are ignored. Each
-            letter refers to a side (north, south, east, or west)
-            that the window will "stick" to. If both n and s
-            (or e and w) are specified, the window will be
-            stretched to fill the entire height (or width) of
-            its cavity.
-        width size
-            Specify a width for the window. The width will be
-            the outer dimension of the window including its
-            border, if any. If size is an empty string, or
-            if -width is not specified, then the width requested
-            internally by the window will be used initially; the
-            width may later be adjusted by the movement of sashes
-            in the panedwindow. Size may be any value accepted by
-            Tk_GetPixels.
-
-        """
-        if cnf is None and not kw:
-            cnf = {}
-            for x in self.tk.split(
-                self.tk.call(self._w,
-                         'paneconfigure', tagOrId)):
-                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
-            return cnf
-        if type(cnf) == StringType and not kw:
-            x = self.tk.split(self.tk.call(
-                self._w, 'paneconfigure', tagOrId, '-'+cnf))
-            return (x[0][1:],) + x[1:]
-        self.tk.call((self._w, 'paneconfigure', tagOrId) +
-                 self._options(cnf, kw))
-    paneconfig = paneconfigure
-
-    def panes(self):
-        """Returns an ordered list of the child panes."""
-        return self.tk.call(self._w, 'panes')
-
-######################################################################
-# Extensions:
-
-class Studbutton(Button):
-    def __init__(self, master=None, cnf={}, **kw):
-        Widget.__init__(self, master, 'studbutton', cnf, kw)
-        self.bind('<Any-Enter>',       self.tkButtonEnter)
-        self.bind('<Any-Leave>',       self.tkButtonLeave)
-        self.bind('<1>',               self.tkButtonDown)
-        self.bind('<ButtonRelease-1>', self.tkButtonUp)
-
-class Tributton(Button):
-    def __init__(self, master=None, cnf={}, **kw):
-        Widget.__init__(self, master, 'tributton', cnf, kw)
-        self.bind('<Any-Enter>',       self.tkButtonEnter)
-        self.bind('<Any-Leave>',       self.tkButtonLeave)
-        self.bind('<1>',               self.tkButtonDown)
-        self.bind('<ButtonRelease-1>', self.tkButtonUp)
-        self['fg']               = self['bg']
-        self['activebackground'] = self['bg']
-
-######################################################################
-# Test:
-
-def _test():
-    root = Tk()
-    text = "This is Tcl/Tk version %s" % TclVersion
-    if TclVersion >= 8.1:
-        try:
-            text = text + unicode("\nThis should be a cedilla: \347",
-                                  "iso-8859-1")
-        except NameError:
-            pass # no unicode support
-    label = Label(root, text=text)
-    label.pack()
-    test = Button(root, text="Click me!",
-              command=lambda root=root: root.test.configure(
-                  text="[%s]" % root.test['text']))
-    test.pack()
-    root.test = test
-    quit = Button(root, text="QUIT", command=root.destroy)
-    quit.pack()
-    # The following three commands are needed so the window pops
-    # up on top on Windows...
-    root.iconify()
-    root.update()
-    root.deiconify()
-    root.mainloop()
-
-if __name__ == '__main__':
-    _test()
diff --git a/Lib/tkinter/_fix.py b/Lib/tkinter/_fix.py
deleted file mode 100644
index 346d3c3..0000000
--- a/Lib/tkinter/_fix.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import sys, os
-
-# Delay import _tkinter until we have set TCL_LIBRARY,
-# so that Tcl_FindExecutable has a chance to locate its
-# encoding directory.
-
-# Unfortunately, we cannot know the TCL_LIBRARY directory
-# if we don't know the tcl version, which we cannot find out
-# without import Tcl. Fortunately, Tcl will itself look in
-# <TCL_LIBRARY>\..\tcl<TCL_VERSION>, so anything close to
-# the real Tcl library will do.
-
-prefix = os.path.join(sys.prefix,"tcl")
-if not os.path.exists(prefix):
-    # devdir/../tcltk/lib
-    prefix = os.path.join(sys.prefix, os.path.pardir, "tcltk", "lib")
-    prefix = os.path.abspath(prefix)
-# if this does not exist, no further search is needed
-if os.path.exists(prefix):
-    if not os.environ.has_key("TCL_LIBRARY"):
-        for name in os.listdir(prefix):
-            if name.startswith("tcl"):
-                tcldir = os.path.join(prefix,name)
-                if os.path.isdir(tcldir):
-                    os.environ["TCL_LIBRARY"] = tcldir
-    # Compute TK_LIBRARY, knowing that it has the same version
-    # as Tcl
-    import _tkinter
-    ver = str(_tkinter.TCL_VERSION)
-    if not os.environ.has_key("TK_LIBRARY"):
-        v = os.path.join(prefix, 'tk'+ver)
-        if os.path.exists(os.path.join(v, "tclIndex")):
-            os.environ['TK_LIBRARY'] = v
-    # We don't know the Tix version, so we must search the entire
-    # directory
-    if not os.environ.has_key("TIX_LIBRARY"):
-        for name in os.listdir(prefix):
-            if name.startswith("tix"):
-                tixdir = os.path.join(prefix,name)
-                if os.path.isdir(tixdir):
-                    os.environ["TIX_LIBRARY"] = tixdir
diff --git a/Lib/tkinter/colorchooser.py b/Lib/tkinter/colorchooser.py
deleted file mode 100644
index 77b391a..0000000
--- a/Lib/tkinter/colorchooser.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# tk common colour chooser dialogue
-#
-# this module provides an interface to the native color dialogue
-# available in Tk 4.2 and newer.
-#
-# written by Fredrik Lundh, May 1997
-#
-# fixed initialcolor handling in August 1998
-#
-
-#
-# options (all have default values):
-#
-# - initialcolor: colour to mark as selected when dialog is displayed
-#   (given as an RGB triplet or a Tk color string)
-#
-# - parent: which window to place the dialog on top of
-#
-# - title: dialog title
-#
-
-from tkinter.commondialog import Dialog
-
-
-#
-# color chooser class
-
-class Chooser(Dialog):
-    "Ask for a color"
-
-    command = "tk_chooseColor"
-
-    def _fixoptions(self):
-        try:
-            # make sure initialcolor is a tk color string
-            color = self.options["initialcolor"]
-            if type(color) == type(()):
-                # assume an RGB triplet
-                self.options["initialcolor"] = "#%02x%02x%02x" % color
-        except KeyError:
-            pass
-
-    def _fixresult(self, widget, result):
-        # to simplify application code, the color chooser returns
-        # an RGB tuple together with the Tk color string
-        if not result:
-            return None, None # canceled
-        r, g, b = widget.winfo_rgb(result)
-        return (r/256, g/256, b/256), result
-
-
-#
-# convenience stuff
-
-def askcolor(color = None, **options):
-    "Ask for a color"
-
-    if color:
-        options = options.copy()
-        options["initialcolor"] = color
-
-    return Chooser(**options).show()
-
-
-# --------------------------------------------------------------------
-# test stuff
-
-if __name__ == "__main__":
-
-    print "color", askcolor()
diff --git a/Lib/tkinter/commondialog.py b/Lib/tkinter/commondialog.py
deleted file mode 100644
index f61eb45..0000000
--- a/Lib/tkinter/commondialog.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# base class for tk common dialogues
-#
-# this module provides a base class for accessing the common
-# dialogues available in Tk 4.2 and newer.  use filedialog,
-# colorchooser, and messagebox to access the individual
-# dialogs.
-#
-# written by Fredrik Lundh, May 1997
-#
-
-from tkinter import *
-
-class Dialog:
-
-    command  = None
-
-    def __init__(self, master=None, **options):
-
-        # FIXME: should this be placed on the module level instead?
-        if TkVersion < 4.2:
-            raise TclError, "this module requires Tk 4.2 or newer"
-
-        self.master  = master
-        self.options = options
-        if not master and options.get('parent'):
-            self.master = options['parent']
-
-    def _fixoptions(self):
-        pass # hook
-
-    def _fixresult(self, widget, result):
-        return result # hook
-
-    def show(self, **options):
-
-        # update instance options
-        for k, v in options.items():
-            self.options[k] = v
-
-        self._fixoptions()
-
-        # we need a dummy widget to properly process the options
-        # (at least as long as we use Tkinter 1.63)
-        w = Frame(self.master)
-
-        try:
-
-            s = w.tk.call(self.command, *w._options(self.options))
-
-            s = self._fixresult(w, s)
-
-        finally:
-
-            try:
-                # get rid of the widget
-                w.destroy()
-            except:
-                pass
-
-        return s
diff --git a/Lib/tkinter/constants.py b/Lib/tkinter/constants.py
deleted file mode 100644
index 63eee33..0000000
--- a/Lib/tkinter/constants.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Symbolic constants for Tk
-
-# Booleans
-NO=FALSE=OFF=0
-YES=TRUE=ON=1
-
-# -anchor and -sticky
-N='n'
-S='s'
-W='w'
-E='e'
-NW='nw'
-SW='sw'
-NE='ne'
-SE='se'
-NS='ns'
-EW='ew'
-NSEW='nsew'
-CENTER='center'
-
-# -fill
-NONE='none'
-X='x'
-Y='y'
-BOTH='both'
-
-# -side
-LEFT='left'
-TOP='top'
-RIGHT='right'
-BOTTOM='bottom'
-
-# -relief
-RAISED='raised'
-SUNKEN='sunken'
-FLAT='flat'
-RIDGE='ridge'
-GROOVE='groove'
-SOLID = 'solid'
-
-# -orient
-HORIZONTAL='horizontal'
-VERTICAL='vertical'
-
-# -tabs
-NUMERIC='numeric'
-
-# -wrap
-CHAR='char'
-WORD='word'
-
-# -align
-BASELINE='baseline'
-
-# -bordermode
-INSIDE='inside'
-OUTSIDE='outside'
-
-# Special tags, marks and insert positions
-SEL='sel'
-SEL_FIRST='sel.first'
-SEL_LAST='sel.last'
-END='end'
-INSERT='insert'
-CURRENT='current'
-ANCHOR='anchor'
-ALL='all' # e.g. Canvas.delete(ALL)
-
-# Text widget and button states
-NORMAL='normal'
-DISABLED='disabled'
-ACTIVE='active'
-# Canvas state
-HIDDEN='hidden'
-
-# Menu item types
-CASCADE='cascade'
-CHECKBUTTON='checkbutton'
-COMMAND='command'
-RADIOBUTTON='radiobutton'
-SEPARATOR='separator'
-
-# Selection modes for list boxes
-SINGLE='single'
-BROWSE='browse'
-MULTIPLE='multiple'
-EXTENDED='extended'
-
-# Activestyle for list boxes
-# NONE='none' is also valid
-DOTBOX='dotbox'
-UNDERLINE='underline'
-
-# Various canvas styles
-PIESLICE='pieslice'
-CHORD='chord'
-ARC='arc'
-FIRST='first'
-LAST='last'
-BUTT='butt'
-PROJECTING='projecting'
-ROUND='round'
-BEVEL='bevel'
-MITER='miter'
-
-# Arguments to xview/yview
-MOVETO='moveto'
-SCROLL='scroll'
-UNITS='units'
-PAGES='pages'
diff --git a/Lib/tkinter/dialog.py b/Lib/tkinter/dialog.py
deleted file mode 100644
index 75e7fed..0000000
--- a/Lib/tkinter/dialog.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# dialog.py -- Tkinter interface to the tk_dialog script.
-
-from tkinter import *
-from tkinter import _cnfmerge
-
-if TkVersion <= 3.6:
-    DIALOG_ICON = 'warning'
-else:
-    DIALOG_ICON = 'questhead'
-
-
-class Dialog(Widget):
-    def __init__(self, master=None, cnf={}, **kw):
-        cnf = _cnfmerge((cnf, kw))
-        self.widgetName = '__dialog__'
-        Widget._setup(self, master, cnf)
-        self.num = self.tk.getint(
-                self.tk.call(
-                      'tk_dialog', self._w,
-                      cnf['title'], cnf['text'],
-                      cnf['bitmap'], cnf['default'],
-                      *cnf['strings']))
-        try: Widget.destroy(self)
-        except TclError: pass
-    def destroy(self): pass
-
-def _test():
-    d = Dialog(None, {'title': 'File Modified',
-                      'text':
-                      'File "Python.h" has been modified'
-                      ' since the last time it was saved.'
-                      ' Do you want to save it before'
-                      ' exiting the application.',
-                      'bitmap': DIALOG_ICON,
-                      'default': 0,
-                      'strings': ('Save File',
-                                  'Discard Changes',
-                                  'Return to Editor')})
-    print d.num
-
-
-if __name__ == '__main__':
-    t = Button(None, {'text': 'Test',
-                      'command': _test,
-                      Pack: {}})
-    q = Button(None, {'text': 'Quit',
-                      'command': t.quit,
-                      Pack: {}})
-    t.mainloop()
diff --git a/Lib/tkinter/dnd.py b/Lib/tkinter/dnd.py
deleted file mode 100644
index 55f0776..0000000
--- a/Lib/tkinter/dnd.py
+++ /dev/null
@@ -1,321 +0,0 @@
-"""Drag-and-drop support for Tkinter.
-
-This is very preliminary.  I currently only support dnd *within* one
-application, between different windows (or within the same window).
-
-I an trying to make this as generic as possible -- not dependent on
-the use of a particular widget or icon type, etc.  I also hope that
-this will work with Pmw.
-
-To enable an object to be dragged, you must create an event binding
-for it that starts the drag-and-drop process. Typically, you should
-bind <ButtonPress> to a callback function that you write. The function
-should call Tkdnd.dnd_start(source, event), where 'source' is the
-object to be dragged, and 'event' is the event that invoked the call
-(the argument to your callback function).  Even though this is a class
-instantiation, the returned instance should not be stored -- it will
-be kept alive automatically for the duration of the drag-and-drop.
-
-When a drag-and-drop is already in process for the Tk interpreter, the
-call is *ignored*; this normally averts starting multiple simultaneous
-dnd processes, e.g. because different button callbacks all
-dnd_start().
-
-The object is *not* necessarily a widget -- it can be any
-application-specific object that is meaningful to potential
-drag-and-drop targets.
-
-Potential drag-and-drop targets are discovered as follows.  Whenever
-the mouse moves, and at the start and end of a drag-and-drop move, the
-Tk widget directly under the mouse is inspected.  This is the target
-widget (not to be confused with the target object, yet to be
-determined).  If there is no target widget, there is no dnd target
-object.  If there is a target widget, and it has an attribute
-dnd_accept, this should be a function (or any callable object).  The
-function is called as dnd_accept(source, event), where 'source' is the
-object being dragged (the object passed to dnd_start() above), and
-'event' is the most recent event object (generally a <Motion> event;
-it can also be <ButtonPress> or <ButtonRelease>).  If the dnd_accept()
-function returns something other than None, this is the new dnd target
-object.  If dnd_accept() returns None, or if the target widget has no
-dnd_accept attribute, the target widget's parent is considered as the
-target widget, and the search for a target object is repeated from
-there.  If necessary, the search is repeated all the way up to the
-root widget.  If none of the target widgets can produce a target
-object, there is no target object (the target object is None).
-
-The target object thus produced, if any, is called the new target
-object.  It is compared with the old target object (or None, if there
-was no old target widget).  There are several cases ('source' is the
-source object, and 'event' is the most recent event object):
-
-- Both the old and new target objects are None.  Nothing happens.
-
-- The old and new target objects are the same object.  Its method
-dnd_motion(source, event) is called.
-
-- The old target object was None, and the new target object is not
-None.  The new target object's method dnd_enter(source, event) is
-called.
-
-- The new target object is None, and the old target object is not
-None.  The old target object's method dnd_leave(source, event) is
-called.
-
-- The old and new target objects differ and neither is None.  The old
-target object's method dnd_leave(source, event), and then the new
-target object's method dnd_enter(source, event) is called.
-
-Once this is done, the new target object replaces the old one, and the
-Tk mainloop proceeds.  The return value of the methods mentioned above
-is ignored; if they raise an exception, the normal exception handling
-mechanisms take over.
-
-The drag-and-drop processes can end in two ways: a final target object
-is selected, or no final target object is selected.  When a final
-target object is selected, it will always have been notified of the
-potential drop by a call to its dnd_enter() method, as described
-above, and possibly one or more calls to its dnd_motion() method; its
-dnd_leave() method has not been called since the last call to
-dnd_enter().  The target is notified of the drop by a call to its
-method dnd_commit(source, event).
-
-If no final target object is selected, and there was an old target
-object, its dnd_leave(source, event) method is called to complete the
-dnd sequence.
-
-Finally, the source object is notified that the drag-and-drop process
-is over, by a call to source.dnd_end(target, event), specifying either
-the selected target object, or None if no target object was selected.
-The source object can use this to implement the commit action; this is
-sometimes simpler than to do it in the target's dnd_commit().  The
-target's dnd_commit() method could then simply be aliased to
-dnd_leave().
-
-At any time during a dnd sequence, the application can cancel the
-sequence by calling the cancel() method on the object returned by
-dnd_start().  This will call dnd_leave() if a target is currently
-active; it will never call dnd_commit().
-
-"""
-
-
-import tkinter
-
-
-# The factory function
-
-def dnd_start(source, event):
-    h = DndHandler(source, event)
-    if h.root:
-        return h
-    else:
-        return None
-
-
-# The class that does the work
-
-class DndHandler:
-
-    root = None
-
-    def __init__(self, source, event):
-        if event.num > 5:
-            return
-        root = event.widget._root()
-        try:
-            root.__dnd
-            return # Don't start recursive dnd
-        except AttributeError:
-            root.__dnd = self
-            self.root = root
-        self.source = source
-        self.target = None
-        self.initial_button = button = event.num
-        self.initial_widget = widget = event.widget
-        self.release_pattern = "<B%d-ButtonRelease-%d>" % (button, button)
-        self.save_cursor = widget['cursor'] or ""
-        widget.bind(self.release_pattern, self.on_release)
-        widget.bind("<Motion>", self.on_motion)
-        widget['cursor'] = "hand2"
-
-    def __del__(self):
-        root = self.root
-        self.root = None
-        if root:
-            try:
-                del root.__dnd
-            except AttributeError:
-                pass
-
-    def on_motion(self, event):
-        x, y = event.x_root, event.y_root
-        target_widget = self.initial_widget.winfo_containing(x, y)
-        source = self.source
-        new_target = None
-        while target_widget:
-            try:
-                attr = target_widget.dnd_accept
-            except AttributeError:
-                pass
-            else:
-                new_target = attr(source, event)
-                if new_target:
-                    break
-            target_widget = target_widget.master
-        old_target = self.target
-        if old_target is new_target:
-            if old_target:
-                old_target.dnd_motion(source, event)
-        else:
-            if old_target:
-                self.target = None
-                old_target.dnd_leave(source, event)
-            if new_target:
-                new_target.dnd_enter(source, event)
-                self.target = new_target
-
-    def on_release(self, event):
-        self.finish(event, 1)
-
-    def cancel(self, event=None):
-        self.finish(event, 0)
-
-    def finish(self, event, commit=0):
-        target = self.target
-        source = self.source
-        widget = self.initial_widget
-        root = self.root
-        try:
-            del root.__dnd
-            self.initial_widget.unbind(self.release_pattern)
-            self.initial_widget.unbind("<Motion>")
-            widget['cursor'] = self.save_cursor
-            self.target = self.source = self.initial_widget = self.root = None
-            if target:
-                if commit:
-                    target.dnd_commit(source, event)
-                else:
-                    target.dnd_leave(source, event)
-        finally:
-            source.dnd_end(target, event)
-
-
-
-# ----------------------------------------------------------------------
-# The rest is here for testing and demonstration purposes only!
-
-class Icon:
-
-    def __init__(self, name):
-        self.name = name
-        self.canvas = self.label = self.id = None
-
-    def attach(self, canvas, x=10, y=10):
-        if canvas is self.canvas:
-            self.canvas.coords(self.id, x, y)
-            return
-        if self.canvas:
-            self.detach()
-        if not canvas:
-            return
-        label = tkinter.Label(canvas, text=self.name,
-                              borderwidth=2, relief="raised")
-        id = canvas.create_window(x, y, window=label, anchor="nw")
-        self.canvas = canvas
-        self.label = label
-        self.id = id
-        label.bind("<ButtonPress>", self.press)
-
-    def detach(self):
-        canvas = self.canvas
-        if not canvas:
-            return
-        id = self.id
-        label = self.label
-        self.canvas = self.label = self.id = None
-        canvas.delete(id)
-        label.destroy()
-
-    def press(self, event):
-        if dnd_start(self, event):
-            # where the pointer is relative to the label widget:
-            self.x_off = event.x
-            self.y_off = event.y
-            # where the widget is relative to the canvas:
-            self.x_orig, self.y_orig = self.canvas.coords(self.id)
-
-    def move(self, event):
-        x, y = self.where(self.canvas, event)
-        self.canvas.coords(self.id, x, y)
-
-    def putback(self):
-        self.canvas.coords(self.id, self.x_orig, self.y_orig)
-
-    def where(self, canvas, event):
-        # where the corner of the canvas is relative to the screen:
-        x_org = canvas.winfo_rootx()
-        y_org = canvas.winfo_rooty()
-        # where the pointer is relative to the canvas widget:
-        x = event.x_root - x_org
-        y = event.y_root - y_org
-        # compensate for initial pointer offset
-        return x - self.x_off, y - self.y_off
-
-    def dnd_end(self, target, event):
-        pass
-
-class Tester:
-
-    def __init__(self, root):
-        self.top = tkinter.Toplevel(root)
-        self.canvas = tkinter.Canvas(self.top, width=100, height=100)
-        self.canvas.pack(fill="both", expand=1)
-        self.canvas.dnd_accept = self.dnd_accept
-
-    def dnd_accept(self, source, event):
-        return self
-
-    def dnd_enter(self, source, event):
-        self.canvas.focus_set() # Show highlight border
-        x, y = source.where(self.canvas, event)
-        x1, y1, x2, y2 = source.canvas.bbox(source.id)
-        dx, dy = x2-x1, y2-y1
-        self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy)
-        self.dnd_motion(source, event)
-
-    def dnd_motion(self, source, event):
-        x, y = source.where(self.canvas, event)
-        x1, y1, x2, y2 = self.canvas.bbox(self.dndid)
-        self.canvas.move(self.dndid, x-x1, y-y1)
-
-    def dnd_leave(self, source, event):
-        self.top.focus_set() # Hide highlight border
-        self.canvas.delete(self.dndid)
-        self.dndid = None
-
-    def dnd_commit(self, source, event):
-        self.dnd_leave(source, event)
-        x, y = source.where(self.canvas, event)
-        source.attach(self.canvas, x, y)
-
-def test():
-    root = tkinter.Tk()
-    root.geometry("+1+1")
-    tkinter.Button(command=root.quit, text="Quit").pack()
-    t1 = Tester(root)
-    t1.top.geometry("+1+60")
-    t2 = Tester(root)
-    t2.top.geometry("+120+60")
-    t3 = Tester(root)
-    t3.top.geometry("+240+60")
-    i1 = Icon("ICON1")
-    i2 = Icon("ICON2")
-    i3 = Icon("ICON3")
-    i1.attach(t1.canvas)
-    i2.attach(t2.canvas)
-    i3.attach(t3.canvas)
-    root.mainloop()
-
-if __name__ == '__main__':
-    test()
diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py
deleted file mode 100644
index c23f047..0000000
--- a/Lib/tkinter/font.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Tkinter font wrapper
-#
-# written by Fredrik Lundh, February 1998
-#
-# FIXME: should add 'displayof' option where relevant (actual, families,
-#        measure, and metrics)
-#
-
-__version__ = "0.9"
-
-import tkinter
-
-# weight/slant
-NORMAL = "normal"
-ROMAN = "roman"
-BOLD   = "bold"
-ITALIC = "italic"
-
-def nametofont(name):
-    """Given the name of a tk named font, returns a Font representation.
-    """
-    return Font(name=name, exists=True)
-
-class Font:
-
-    """Represents a named font.
-
-    Constructor options are:
-
-    font -- font specifier (name, system font, or (family, size, style)-tuple)
-    name -- name to use for this font configuration (defaults to a unique name)
-    exists -- does a named font by this name already exist?
-       Creates a new named font if False, points to the existing font if True.
-       Raises _tkinter.TclError if the assertion is false.
-
-       the following are ignored if font is specified:
-
-    family -- font 'family', e.g. Courier, Times, Helvetica
-    size -- font size in points
-    weight -- font thickness: NORMAL, BOLD
-    slant -- font slant: ROMAN, ITALIC
-    underline -- font underlining: false (0), true (1)
-    overstrike -- font strikeout: false (0), true (1)
-
-    """
-
-    def _set(self, kw):
-        options = []
-        for k, v in kw.items():
-            options.append("-"+k)
-            options.append(str(v))
-        return tuple(options)
-
-    def _get(self, args):
-        options = []
-        for k in args:
-            options.append("-"+k)
-        return tuple(options)
-
-    def _mkdict(self, args):
-        options = {}
-        for i in range(0, len(args), 2):
-            options[args[i][1:]] = args[i+1]
-        return options
-
-    def __init__(self, root=None, font=None, name=None, exists=False, **options):
-        if not root:
-            root = tkinter._default_root
-        if font:
-            # get actual settings corresponding to the given font
-            font = root.tk.splitlist(root.tk.call("font", "actual", font))
-        else:
-            font = self._set(options)
-        if not name:
-            name = "font" + str(id(self))
-        self.name = name
-
-        if exists:
-            self.delete_font = False
-            # confirm font exists
-            if self.name not in root.tk.call("font", "names"):
-                raise tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,)
-            # if font config info supplied, apply it
-            if font:
-                root.tk.call("font", "configure", self.name, *font)
-        else:
-            # create new font (raises TclError if the font exists)
-            root.tk.call("font", "create", self.name, *font)
-            self.delete_font = True
-        # backlinks!
-        self._root  = root
-        self._split = root.tk.splitlist
-        self._call  = root.tk.call
-
-    def __str__(self):
-        return self.name
-
-    def __eq__(self, other):
-        return self.name == other.name and isinstance(other, Font)
-
-    def __getitem__(self, key):
-        return self.cget(key)
-
-    def __setitem__(self, key, value):
-        self.configure(**{key: value})
-
-    def __del__(self):
-        try:
-            if self.delete_font:
-                self._call("font", "delete", self.name)
-        except (KeyboardInterrupt, SystemExit):
-            raise
-        except Exception:
-            pass
-
-    def copy(self):
-        "Return a distinct copy of the current font"
-        return Font(self._root, **self.actual())
-
-    def actual(self, option=None):
-        "Return actual font attributes"
-        if option:
-            return self._call("font", "actual", self.name, "-"+option)
-        else:
-            return self._mkdict(
-                self._split(self._call("font", "actual", self.name))
-                )
-
-    def cget(self, option):
-        "Get font attribute"
-        return self._call("font", "config", self.name, "-"+option)
-
-    def config(self, **options):
-        "Modify font attributes"
-        if options:
-            self._call("font", "config", self.name,
-                  *self._set(options))
-        else:
-            return self._mkdict(
-                self._split(self._call("font", "config", self.name))
-                )
-
-    configure = config
-
-    def measure(self, text):
-        "Return text width"
-        return int(self._call("font", "measure", self.name, text))
-
-    def metrics(self, *options):
-        """Return font metrics.
-
-        For best performance, create a dummy widget
-        using this font before calling this method."""
-
-        if options:
-            return int(
-                self._call("font", "metrics", self.name, self._get(options))
-                )
-        else:
-            res = self._split(self._call("font", "metrics", self.name))
-            options = {}
-            for i in range(0, len(res), 2):
-                options[res[i][1:]] = int(res[i+1])
-            return options
-
-def families(root=None):
-    "Get font families (as a tuple)"
-    if not root:
-        root = tkinter._default_root
-    return root.tk.splitlist(root.tk.call("font", "families"))
-
-def names(root=None):
-    "Get names of defined fonts (as a tuple)"
-    if not root:
-        root = tkinter._default_root
-    return root.tk.splitlist(root.tk.call("font", "names"))
-
-# --------------------------------------------------------------------
-# test stuff
-
-if __name__ == "__main__":
-
-    root = tkinter.Tk()
-
-    # create a font
-    f = Font(family="times", size=30, weight=NORMAL)
-
-    print f.actual()
-    print f.actual("family")
-    print f.actual("weight")
-
-    print f.config()
-    print f.cget("family")
-    print f.cget("weight")
-
-    print names()
-
-    print f.measure("hello"), f.metrics("linespace")
-
-    print f.metrics()
-
-    f = Font(font=("Courier", 20, "bold"))
-    print f.measure("hello"), f.metrics("linespace")
-
-    w = tkinter.Label(root, text="Hello, world", font=f)
-    w.pack()
-
-    w = tkinter.Button(root, text="Quit!", command=root.destroy)
-    w.pack()
-
-    fb = Font(font=w["font"]).copy()
-    fb.config(weight=BOLD)
-
-    w.config(font=fb)
-
-    tkinter.mainloop()
diff --git a/Lib/tkinter/messagebox.py b/Lib/tkinter/messagebox.py
deleted file mode 100644
index df0a163..0000000
--- a/Lib/tkinter/messagebox.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# tk common message boxes
-#
-# this module provides an interface to the native message boxes
-# available in Tk 4.2 and newer.
-#
-# written by Fredrik Lundh, May 1997
-#
-
-#
-# options (all have default values):
-#
-# - default: which button to make default (one of the reply codes)
-#
-# - icon: which icon to display (see below)
-#
-# - message: the message to display
-#
-# - parent: which window to place the dialog on top of
-#
-# - title: dialog title
-#
-# - type: dialog type; that is, which buttons to display (see below)
-#
-
-from tkinter.commondialog import Dialog
-
-#
-# constants
-
-# icons
-ERROR = "error"
-INFO = "info"
-QUESTION = "question"
-WARNING = "warning"
-
-# types
-ABORTRETRYIGNORE = "abortretryignore"
-OK = "ok"
-OKCANCEL = "okcancel"
-RETRYCANCEL = "retrycancel"
-YESNO = "yesno"
-YESNOCANCEL = "yesnocancel"
-
-# replies
-ABORT = "abort"
-RETRY = "retry"
-IGNORE = "ignore"
-OK = "ok"
-CANCEL = "cancel"
-YES = "yes"
-NO = "no"
-
-
-#
-# message dialog class
-
-class Message(Dialog):
-    "A message box"
-
-    command  = "tk_messageBox"
-
-
-#
-# convenience stuff
-
-# Rename _icon and _type options to allow overriding them in options
-def _show(title=None, message=None, _icon=None, _type=None, **options):
-    if _icon and "icon" not in options:    options["icon"] = _icon
-    if _type and "type" not in options:    options["type"] = _type
-    if title:   options["title"] = title
-    if message: options["message"] = message
-    res = Message(**options).show()
-    # In some Tcl installations, Tcl converts yes/no into a boolean
-    if isinstance(res, bool):
-        if res: return YES
-        return NO
-    return res
-
-def showinfo(title=None, message=None, **options):
-    "Show an info message"
-    return _show(title, message, INFO, OK, **options)
-
-def showwarning(title=None, message=None, **options):
-    "Show a warning message"
-    return _show(title, message, WARNING, OK, **options)
-
-def showerror(title=None, message=None, **options):
-    "Show an error message"
-    return _show(title, message, ERROR, OK, **options)
-
-def askquestion(title=None, message=None, **options):
-    "Ask a question"
-    return _show(title, message, QUESTION, YESNO, **options)
-
-def askokcancel(title=None, message=None, **options):
-    "Ask if operation should proceed; return true if the answer is ok"
-    s = _show(title, message, QUESTION, OKCANCEL, **options)
-    return s == OK
-
-def askyesno(title=None, message=None, **options):
-    "Ask a question; return true if the answer is yes"
-    s = _show(title, message, QUESTION, YESNO, **options)
-    return s == YES
-
-def askyesnocancel(title=None, message=None, **options):
-    "Ask a question; return true if the answer is yes, None if cancelled."
-    s = _show(title, message, QUESTION, YESNOCANCEL, **options)
-    # s might be a Tcl index object, so convert it to a string
-    s = str(s)
-    if s == CANCEL:
-        return None
-    return s == YES
-
-def askretrycancel(title=None, message=None, **options):
-    "Ask if operation should be retried; return true if the answer is yes"
-    s = _show(title, message, WARNING, RETRYCANCEL, **options)
-    return s == RETRY
-
-
-# --------------------------------------------------------------------
-# test stuff
-
-if __name__ == "__main__":
-
-    print "info", showinfo("Spam", "Egg Information")
-    print "warning", showwarning("Spam", "Egg Warning")
-    print "error", showerror("Spam", "Egg Alert")
-    print "question", askquestion("Spam", "Question?")
-    print "proceed", askokcancel("Spam", "Proceed?")
-    print "yes/no", askyesno("Spam", "Got it?")
-    print "yes/no/cancel", askyesnocancel("Spam", "Want it?")
-    print "try again", askretrycancel("Spam", "Try again?")
diff --git a/Lib/tkinter/scrolledtext.py b/Lib/tkinter/scrolledtext.py
deleted file mode 100644
index c96bc3b..0000000
--- a/Lib/tkinter/scrolledtext.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# A ScrolledText widget feels like a text widget but also has a
-# vertical scroll bar on its right.  (Later, options may be added to
-# add a horizontal bar as well, to make the bars disappear
-# automatically when not needed, to move them to the other side of the
-# window, etc.)
-#
-# Configuration options are passed to the Text widget.
-# A Frame widget is inserted between the master and the text, to hold
-# the Scrollbar widget.
-# Most methods calls are inherited from the Text widget; Pack methods
-# are redirected to the Frame widget however.
-
-from tkinter import *
-from tkinter import _cnfmerge
-
-class ScrolledText(Text):
-    def __init__(self, master=None, cnf=None, **kw):
-        if cnf is None:
-            cnf = {}
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        fcnf = {}
-        for k in cnf.keys():
-            if type(k) == ClassType or k == 'name':
-                fcnf[k] = cnf[k]
-                del cnf[k]
-        self.frame = Frame(master, **fcnf)
-        self.vbar = Scrollbar(self.frame, name='vbar')
-        self.vbar.pack(side=RIGHT, fill=Y)
-        cnf['name'] = 'text'
-        Text.__init__(self, self.frame, **cnf)
-        self.pack(side=LEFT, fill=BOTH, expand=1)
-        self['yscrollcommand'] = self.vbar.set
-        self.vbar['command'] = self.yview
-
-        # Copy geometry methods of self.frame -- hack!
-        methods = Pack.__dict__.keys()
-        methods = methods + Grid.__dict__.keys()
-        methods = methods + Place.__dict__.keys()
-
-        for m in methods:
-            if m[0] != '_' and m != 'config' and m != 'configure':
-                setattr(self, m, getattr(self.frame, m))
diff --git a/Lib/tkinter/tix.py b/Lib/tkinter/tix.py
deleted file mode 100755
index 22a9000..0000000
--- a/Lib/tkinter/tix.py
+++ /dev/null
@@ -1,1891 +0,0 @@
-# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
-#
-# $Id$
-#
-# Tix.py -- Tix widget wrappers.
-#
-#       For Tix, see http://tix.sourceforge.net
-#
-#       - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995.
-#         based on an idea of Jean-Marc Lugrin (lugrin@ms.com)
-#
-# NOTE: In order to minimize changes to Tkinter.py, some of the code here
-#       (TixWidget.__init__) has been taken from Tkinter (Widget.__init__)
-#       and will break if there are major changes in Tkinter.
-#
-# The Tix widgets are represented by a class hierarchy in python with proper
-# inheritance of base classes.
-#
-# As a result after creating a 'w = StdButtonBox', I can write
-#              w.ok['text'] = 'Who Cares'
-#    or              w.ok['bg'] = w['bg']
-# or even       w.ok.invoke()
-# etc.
-#
-# Compare the demo tixwidgets.py to the original Tcl program and you will
-# appreciate the advantages.
-#
-
-from tkinter import *
-from tkinter import _flatten, _cnfmerge, _default_root
-
-# WARNING - TkVersion is a limited precision floating point number
-if TkVersion < 3.999:
-    raise ImportError, "This version of Tix.py requires Tk 4.0 or higher"
-
-import _tkinter # If this fails your Python may not be configured for Tk
-
-# Some more constants (for consistency with Tkinter)
-WINDOW = 'window'
-TEXT = 'text'
-STATUS = 'status'
-IMMEDIATE = 'immediate'
-IMAGE = 'image'
-IMAGETEXT = 'imagetext'
-BALLOON = 'balloon'
-AUTO = 'auto'
-ACROSSTOP = 'acrosstop'
-
-# Some constants used by Tkinter dooneevent()
-TCL_DONT_WAIT     = 1 << 1
-TCL_WINDOW_EVENTS = 1 << 2
-TCL_FILE_EVENTS   = 1 << 3
-TCL_TIMER_EVENTS  = 1 << 4
-TCL_IDLE_EVENTS   = 1 << 5
-TCL_ALL_EVENTS    = 0
-
-# BEWARE - this is implemented by copying some code from the Widget class
-#          in Tkinter (to override Widget initialization) and is therefore
-#          liable to break.
-import tkinter, os
-
-# Could probably add this to Tkinter.Misc
-class tixCommand:
-    """The tix commands provide access to miscellaneous  elements
-    of  Tix's  internal state and the Tix application context.
-    Most of the information manipulated by these  commands pertains
-    to  the  application  as a whole, or to a screen or
-    display, rather than to a particular window.
-
-    This is a mixin class, assumed to be mixed to Tkinter.Tk
-    that supports the self.tk.call method.
-    """
-
-    def tix_addbitmapdir(self, directory):
-        """Tix maintains a list of directories under which
-        the  tix_getimage  and tix_getbitmap commands will
-        search for image files. The standard bitmap  directory
-        is $TIX_LIBRARY/bitmaps. The addbitmapdir command
-        adds directory into this list. By  using  this
-        command, the  image  files  of an applications can
-        also be located using the tix_getimage or tix_getbitmap
-        command.
-        """
-        return self.tk.call('tix', 'addbitmapdir', directory)
-
-    def tix_cget(self, option):
-        """Returns  the  current  value  of the configuration
-        option given by option. Option may be  any  of  the
-        options described in the CONFIGURATION OPTIONS section.
-        """
-        return self.tk.call('tix', 'cget', option)
-
-    def tix_configure(self, cnf=None, **kw):
-        """Query or modify the configuration options of the Tix application
-        context. If no option is specified, returns a dictionary all of the
-        available options.  If option is specified with no value, then the
-        command returns a list describing the one named option (this list
-        will be identical to the corresponding sublist of the value
-        returned if no option is specified).  If one or more option-value
-        pairs are specified, then the command modifies the given option(s)
-        to have the given value(s); in this case the command returns an
-        empty string. Option may be any of the configuration options.
-        """
-        # Copied from Tkinter.py
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        elif cnf:
-            cnf = _cnfmerge(cnf)
-        if cnf is None:
-            cnf = {}
-            for x in self.tk.split(self.tk.call('tix', 'configure')):
-                cnf[x[0][1:]] = (x[0][1:],) + x[1:]
-            return cnf
-        if isinstance(cnf, StringType):
-            x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf))
-            return (x[0][1:],) + x[1:]
-        return self.tk.call(('tix', 'configure') + self._options(cnf))
-
-    def tix_filedialog(self, dlgclass=None):
-        """Returns the file selection dialog that may be shared among
-        different calls from this application.  This command will create a
-        file selection dialog widget when it is called the first time. This
-        dialog will be returned by all subsequent calls to tix_filedialog.
-        An optional dlgclass parameter can be passed to specified what type
-        of file selection dialog widget is desired. Possible options are
-        tix FileSelectDialog or tixExFileSelectDialog.
-        """
-        if dlgclass is not None:
-            return self.tk.call('tix', 'filedialog', dlgclass)
-        else:
-            return self.tk.call('tix', 'filedialog')
-
-    def tix_getbitmap(self, name):
-        """Locates a bitmap file of the name name.xpm or name in one of the
-        bitmap directories (see the tix_addbitmapdir command above).  By
-        using tix_getbitmap, you can avoid hard coding the pathnames of the
-        bitmap files in your application. When successful, it returns the
-        complete pathname of the bitmap file, prefixed with the character
-        '@'.  The returned value can be used to configure the -bitmap
-        option of the TK and Tix widgets.
-        """
-        return self.tk.call('tix', 'getbitmap', name)
-
-    def tix_getimage(self, name):
-        """Locates an image file of the name name.xpm, name.xbm or name.ppm
-        in one of the bitmap directories (see the addbitmapdir command
-        above). If more than one file with the same name (but different
-        extensions) exist, then the image type is chosen according to the
-        depth of the X display: xbm images are chosen on monochrome
-        displays and color images are chosen on color displays. By using
-        tix_ getimage, you can advoid hard coding the pathnames of the
-        image files in your application. When successful, this command
-        returns the name of the newly created image, which can be used to
-        configure the -image option of the Tk and Tix widgets.
-        """
-        return self.tk.call('tix', 'getimage', name)
-
-    def tix_option_get(self, name):
-        """Gets  the options  manitained  by  the  Tix
-        scheme mechanism. Available options include:
-
-            active_bg       active_fg      bg
-            bold_font       dark1_bg       dark1_fg
-            dark2_bg        dark2_fg       disabled_fg
-            fg              fixed_font     font
-            inactive_bg     inactive_fg    input1_bg
-            input2_bg       italic_font    light1_bg
-            light1_fg       light2_bg      light2_fg
-            menu_font       output1_bg     output2_bg
-            select_bg       select_fg      selector
-            """
-        # could use self.tk.globalgetvar('tixOption', name)
-        return self.tk.call('tix', 'option', 'get', name)
-
-    def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None):
-        """Resets the scheme and fontset of the Tix application to
-        newScheme and newFontSet, respectively.  This affects only those
-        widgets created after this call. Therefore, it is best to call the
-        resetoptions command before the creation of any widgets in a Tix
-        application.
-
-        The optional parameter newScmPrio can be given to reset the
-        priority level of the Tk options set by the Tix schemes.
-
-        Because of the way Tk handles the X option database, after Tix has
-        been has imported and inited, it is not possible to reset the color
-        schemes and font sets using the tix config command.  Instead, the
-        tix_resetoptions command must be used.
-        """
-        if newScmPrio is not None:
-            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio)
-        else:
-            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet)
-
-class Tk(tkinter.Tk, tixCommand):
-    """Toplevel widget of Tix which represents mostly the main window
-    of an application. It has an associated Tcl interpreter."""
-    def __init__(self, screenName=None, baseName=None, className='Tix'):
-        tkinter.Tk.__init__(self, screenName, baseName, className)
-        tixlib = os.environ.get('TIX_LIBRARY')
-        self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]')
-        if tixlib is not None:
-            self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib)
-            self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib)
-        # Load Tix - this should work dynamically or statically
-        # If it's static, tcl/tix8.1/pkgIndex.tcl should have
-        #               'load {} Tix'
-        # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have
-        #               'load libtix8.1.8.3.so Tix'
-        self.tk.eval('package require Tix')
-
-    def destroy(self):
-        # For safety, remove an delete_window binding before destroy
-        self.protocol("WM_DELETE_WINDOW", "")
-        tkinter.Tk.destroy(self)
-
-# The Tix 'tixForm' geometry manager
-class Form:
-    """The Tix Form geometry manager
-
-    Widgets can be arranged by specifying attachments to other widgets.
-    See Tix documentation for complete details"""
-
-    def config(self, cnf={}, **kw):
-        self.tk.call('tixForm', self._w, *self._options(cnf, kw))
-
-    form = config
-
-    def __setitem__(self, key, value):
-        Form.form(self, {key: value})
-
-    def check(self):
-        return self.tk.call('tixForm', 'check', self._w)
-
-    def forget(self):
-        self.tk.call('tixForm', 'forget', self._w)
-
-    def grid(self, xsize=0, ysize=0):
-        if (not xsize) and (not ysize):
-            x = self.tk.call('tixForm', 'grid', self._w)
-            y = self.tk.splitlist(x)
-            z = ()
-            for x in y:
-                z = z + (self.tk.getint(x),)
-            return z
-        return self.tk.call('tixForm', 'grid', self._w, xsize, ysize)
-
-    def info(self, option=None):
-        if not option:
-            return self.tk.call('tixForm', 'info', self._w)
-        if option[0] != '-':
-            option = '-' + option
-        return self.tk.call('tixForm', 'info', self._w, option)
-
-    def slaves(self):
-        return map(self._nametowidget,
-                   self.tk.splitlist(
-                       self.tk.call(
-                       'tixForm', 'slaves', self._w)))
-
-
-
-tkinter.Widget.__bases__ = tkinter.Widget.__bases__ + (Form,)
-
-class TixWidget(tkinter.Widget):
-    """A TixWidget class is used to package all (or most) Tix widgets.
-
-    Widget initialization is extended in two ways:
-       1) It is possible to give a list of options which must be part of
-       the creation command (so called Tix 'static' options). These cannot be
-       given as a 'config' command later.
-       2) It is possible to give the name of an existing TK widget. These are
-       child widgets created automatically by a Tix mega-widget. The Tk call
-       to create these widgets is therefore bypassed in TixWidget.__init__
-
-    Both options are for use by subclasses only.
-    """
-    def __init__ (self, master=None, widgetName=None,
-                static_options=None, cnf={}, kw={}):
-        # Merge keywords and dictionary arguments
-        if kw:
-            cnf = _cnfmerge((cnf, kw))
-        else:
-            cnf = _cnfmerge(cnf)
-
-        # Move static options into extra. static_options must be
-        # a list of keywords (or None).
-        extra=()
-
-        # 'options' is always a static option
-        if static_options:
-            static_options.append('options')
-        else:
-            static_options = ['options']
-
-        for k,v in cnf.items()[:]:
-            if k in static_options:
-                extra = extra + ('-' + k, v)
-                del cnf[k]
-
-        self.widgetName = widgetName
-        Widget._setup(self, master, cnf)
-
-        # If widgetName is None, this is a dummy creation call where the
-        # corresponding Tk widget has already been created by Tix
-        if widgetName:
-            self.tk.call(widgetName, self._w, *extra)
-
-        # Non-static options - to be done via a 'config' command
-        if cnf:
-            Widget.config(self, cnf)
-
-        # Dictionary to hold subwidget names for easier access. We can't
-        # use the children list because the public Tix names may not be the
-        # same as the pathname component
-        self.subwidget_list = {}
-
-    # We set up an attribute access function so that it is possible to
-    # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello'
-    # when w is a StdButtonBox.
-    # We can even do w.ok.invoke() because w.ok is subclassed from the
-    # Button class if you go through the proper constructors
-    def __getattr__(self, name):
-        if self.subwidget_list.has_key(name):
-            return self.subwidget_list[name]
-        raise AttributeError, name
-
-    def set_silent(self, value):
-        """Set a variable without calling its action routine"""
-        self.tk.call('tixSetSilent', self._w, value)
-
-    def subwidget(self, name):
-        """Return the named subwidget (which must have been created by
-        the sub-class)."""
-        n = self._subwidget_name(name)
-        if not n:
-            raise TclError, "Subwidget " + name + " not child of " + self._name
-        # Remove header of name and leading dot
-        n = n[len(self._w)+1:]
-        return self._nametowidget(n)
-
-    def subwidgets_all(self):
-        """Return all subwidgets."""
-        names = self._subwidget_names()
-        if not names:
-            return []
-        retlist = []
-        for name in names:
-            name = name[len(self._w)+1:]
-            try:
-                retlist.append(self._nametowidget(name))
-            except:
-                # some of the widgets are unknown e.g. border in LabelFrame
-                pass
-        return retlist
-
-    def _subwidget_name(self,name):
-        """Get a subwidget name (returns a String, not a Widget !)"""
-        try:
-            return self.tk.call(self._w, 'subwidget', name)
-        except TclError:
-            return None
-
-    def _subwidget_names(self):
-        """Return the name of all subwidgets."""
-        try:
-            x = self.tk.call(self._w, 'subwidgets', '-all')
-            return self.tk.split(x)
-        except TclError:
-            return None
-
-    def config_all(self, option, value):
-        """Set configuration options for all subwidgets (and self)."""
-        if option == '':
-            return
-        elif not isinstance(option, StringType):
-            option = repr(option)
-        if not isinstance(value, StringType):
-            value = repr(value)
-        names = self._subwidget_names()
-        for name in names:
-            self.tk.call(name, 'configure', '-' + option, value)
-    # These are missing from Tkinter
-    def image_create(self, imgtype, cnf={}, master=None, **kw):
-        if not master:
-            master = tkinter._default_root
-            if not master:
-                raise RuntimeError, 'Too early to create image'
-        if kw and cnf: cnf = _cnfmerge((cnf, kw))
-        elif kw: cnf = kw
-        options = ()
-        for k, v in cnf.items():
-            if callable(v):
-                v = self._register(v)
-            options = options + ('-'+k, v)
-        return master.tk.call(('image', 'create', imgtype,) + options)
-    def image_delete(self, imgname):
-        try:
-            self.tk.call('image', 'delete', imgname)
-        except TclError:
-            # May happen if the root was destroyed
-            pass
-
-# Subwidgets are child widgets created automatically by mega-widgets.
-# In python, we have to create these subwidgets manually to mirror their
-# existence in Tk/Tix.
-class TixSubWidget(TixWidget):
-    """Subwidget class.
-
-    This is used to mirror child widgets automatically created
-    by Tix/Tk as part of a mega-widget in Python (which is not informed
-    of this)"""
-
-    def __init__(self, master, name,
-               destroy_physically=1, check_intermediate=1):
-        if check_intermediate:
-            path = master._subwidget_name(name)
-            try:
-                path = path[len(master._w)+1:]
-                plist = path.split('.')
-            except:
-                plist = []
-
-        if not check_intermediate:
-            # immediate descendant
-            TixWidget.__init__(self, master, None, None, {'name' : name})
-        else:
-            # Ensure that the intermediate widgets exist
-            parent = master
-            for i in range(len(plist) - 1):
-                n = '.'.join(plist[:i+1])
-                try:
-                    w = master._nametowidget(n)
-                    parent = w
-                except KeyError:
-                    # Create the intermediate widget
-                    parent = TixSubWidget(parent, plist[i],
-                                          destroy_physically=0,
-                                          check_intermediate=0)
-            # The Tk widget name is in plist, not in name
-            if plist:
-                name = plist[-1]
-            TixWidget.__init__(self, parent, None, None, {'name' : name})
-        self.destroy_physically = destroy_physically
-
-    def destroy(self):
-        # For some widgets e.g., a NoteBook, when we call destructors,
-        # we must be careful not to destroy the frame widget since this
-        # also destroys the parent NoteBook thus leading to an exception
-        # in Tkinter when it finally calls Tcl to destroy the NoteBook
-        for c in self.children.values(): c.destroy()
-        if self.master.children.has_key(self._name):
-            del self.master.children[self._name]
-        if self.master.subwidget_list.has_key(self._name):
-            del self.master.subwidget_list[self._name]
-        if self.destroy_physically:
-            # This is bypassed only for a few widgets
-            self.tk.call('destroy', self._w)
-
-
-# Useful func. to split Tcl lists and return as a dict. From Tkinter.py
-def _lst2dict(lst):
-    dict = {}
-    for x in lst:
-        dict[x[0][1:]] = (x[0][1:],) + x[1:]
-    return dict
-
-# Useful class to create a display style - later shared by many items.
-# Contributed by Steffen Kremser
-class DisplayStyle:
-    """DisplayStyle - handle configuration options shared by
-    (multiple) Display Items"""
-
-    def __init__(self, itemtype, cnf={}, **kw):
-        master = _default_root              # global from Tkinter
-        if not master and cnf.has_key('refwindow'): master=cnf['refwindow']
-        elif not master and kw.has_key('refwindow'):  master= kw['refwindow']
-        elif not master: raise RuntimeError, "Too early to create display style: no root window"
-        self.tk = master.tk
-        self.stylename = self.tk.call('tixDisplayStyle', itemtype,
-                            *self._options(cnf,kw) )
-
-    def __str__(self):
-        return self.stylename
-
-    def _options(self, cnf, kw):
-        if kw and cnf:
-            cnf = _cnfmerge((cnf, kw))
-        elif kw:
-            cnf = kw
-        opts = ()
-        for k, v in cnf.items():
-            opts = opts + ('-'+k, v)
-        return opts
-
-    def delete(self):
-        self.tk.call(self.stylename, 'delete')
-
-    def __setitem__(self,key,value):
-        self.tk.call(self.stylename, 'configure', '-%s'%key, value)
-
-    def config(self, cnf={}, **kw):
-        return _lst2dict(
-            self.tk.split(
-            self.tk.call(
-                  self.stylename, 'configure', *self._options(cnf,kw))))
-
-    def __getitem__(self,key):
-        return self.tk.call(self.stylename, 'cget', '-%s'%key)
-
-
-######################################################
-### The Tix Widget classes - in alphabetical order ###
-######################################################
-
-class Balloon(TixWidget):
-    """Balloon help widget.
-
-    Subwidget       Class
-    ---------       -----
-    label           Label
-    message         Message"""
-
-    # FIXME: It should inherit -superclass tixShell
-    def __init__(self, master=None, cnf={}, **kw):
-        # static seem to be -installcolormap -initwait -statusbar -cursor
-        static = ['options', 'installcolormap', 'initwait', 'statusbar',
-                  'cursor']
-        TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw)
-        self.subwidget_list['label'] = _dummyLabel(self, 'label',
-                                                   destroy_physically=0)
-        self.subwidget_list['message'] = _dummyLabel(self, 'message',
-                                                     destroy_physically=0)
-
-    def bind_widget(self, widget, cnf={}, **kw):
-        """Bind balloon widget to another.
-        One balloon widget may be bound to several widgets at the same time"""
-        self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw))
-
-    def unbind_widget(self, widget):
-        self.tk.call(self._w, 'unbind', widget._w)
-
-class ButtonBox(TixWidget):
-    """ButtonBox - A container for pushbuttons.
-    Subwidgets are the buttons added with the add method.
-    """
-    def __init__(self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixButtonBox',
-                           ['orientation', 'options'], cnf, kw)
-
-    def add(self, name, cnf={}, **kw):
-        """Add a button with given name to box."""
-
-        btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
-        self.subwidget_list[name] = _dummyButton(self, name)
-        return btn
-
-    def invoke(self, name):
-        if self.subwidget_list.has_key(name):
-            self.tk.call(self._w, 'invoke', name)
-
-class ComboBox(TixWidget):
-    """ComboBox - an Entry field with a dropdown menu. The user can select a
-    choice by either typing in the entry subwdget or selecting from the
-    listbox subwidget.
-
-    Subwidget       Class
-    ---------       -----
-    entry       Entry
-    arrow       Button
-    slistbox    ScrolledListBox
-    tick        Button
-    cross       Button : present if created with the fancy option"""
-
-    # FIXME: It should inherit -superclass tixLabelWidget
-    def __init__ (self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixComboBox',
-                           ['editable', 'dropdown', 'fancy', 'options'],
-                           cnf, kw)
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
-        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
-        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
-                                                                'slistbox')
-        try:
-            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
-            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
-        except TypeError:
-            # unavailable when -fancy not specified
-            pass
-
-    # align
-
-    def add_history(self, str):
-        self.tk.call(self._w, 'addhistory', str)
-
-    def append_history(self, str):
-        self.tk.call(self._w, 'appendhistory', str)
-
-    def insert(self, index, str):
-        self.tk.call(self._w, 'insert', index, str)
-
-    def pick(self, index):
-        self.tk.call(self._w, 'pick', index)
-
-class Control(TixWidget):
-    """Control - An entry field with value change arrows.  The user can
-    adjust the value by pressing the two arrow buttons or by entering
-    the value directly into the entry. The new value will be checked
-    against the user-defined upper and lower limits.
-
-    Subwidget       Class
-    ---------       -----
-    incr       Button
-    decr       Button
-    entry       Entry
-    label       Label"""
-
-    # FIXME: It should inherit -superclass tixLabelWidget
-    def __init__ (self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw)
-        self.subwidget_list['incr'] = _dummyButton(self, 'incr')
-        self.subwidget_list['decr'] = _dummyButton(self, 'decr')
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
-
-    def decrement(self):
-        self.tk.call(self._w, 'decr')
-
-    def increment(self):
-        self.tk.call(self._w, 'incr')
-
-    def invoke(self):
-        self.tk.call(self._w, 'invoke')
-
-    def update(self):
-        self.tk.call(self._w, 'update')
-
-class DirList(TixWidget):
-    """DirList - displays a list view of a directory, its previous
-    directories and its sub-directories. The user can choose one of
-    the directories displayed in the list or change to another directory.
-
-    Subwidget       Class
-    ---------       -----
-    hlist       HList
-    hsb              Scrollbar
-    vsb              Scrollbar"""
-
-    # FIXME: It should inherit -superclass tixScrolledHList
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-    def chdir(self, dir):
-        self.tk.call(self._w, 'chdir', dir)
-
-class DirTree(TixWidget):
-    """DirTree - Directory Listing in a hierarchical view.
-    Displays a tree view of a directory, its previous directories and its
-    sub-directories. The user can choose one of the directories displayed
-    in the list or change to another directory.
-
-    Subwidget       Class
-    ---------       -----
-    hlist           HList
-    hsb             Scrollbar
-    vsb             Scrollbar"""
-
-    # FIXME: It should inherit -superclass tixScrolledHList
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-    def chdir(self, dir):
-        self.tk.call(self._w, 'chdir', dir)
-
-class DirSelectBox(TixWidget):
-    """DirSelectBox - Motif style file select box.
-    It is generally used for
-    the user to choose a file. FileSelectBox stores the files mostly
-    recently selected into a ComboBox widget so that they can be quickly
-    selected again.
-
-    Subwidget       Class
-    ---------       -----
-    selection       ComboBox
-    filter          ComboBox
-    dirlist         ScrolledListBox
-    filelist        ScrolledListBox"""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw)
-        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
-        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
-
-class ExFileSelectBox(TixWidget):
-    """ExFileSelectBox - MS Windows style file select box.
-    It provides an convenient method for the user to select files.
-
-    Subwidget       Class
-    ---------       -----
-    cancel       Button
-    ok              Button
-    hidden       Checkbutton
-    types       ComboBox
-    dir              ComboBox
-    file       ComboBox
-    dirlist       ScrolledListBox
-    filelist       ScrolledListBox"""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw)
-        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
-        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
-        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
-        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
-        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
-        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
-        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
-        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
-
-    def filter(self):
-        self.tk.call(self._w, 'filter')
-
-    def invoke(self):
-        self.tk.call(self._w, 'invoke')
-
-
-# Should inherit from a Dialog class
-class DirSelectDialog(TixWidget):
-    """The DirSelectDialog widget presents the directories in the file
-    system in a dialog window. The user can use this dialog window to
-    navigate through the file system to select the desired directory.
-
-    Subwidgets       Class
-    ----------       -----
-    dirbox       DirSelectDialog"""
-
-    # FIXME: It should inherit -superclass tixDialogShell
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixDirSelectDialog',
-                           ['options'], cnf, kw)
-        self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox')
-        # cancel and ok buttons are missing
-
-    def popup(self):
-        self.tk.call(self._w, 'popup')
-
-    def popdown(self):
-        self.tk.call(self._w, 'popdown')
-
-
-# Should inherit from a Dialog class
-class ExFileSelectDialog(TixWidget):
-    """ExFileSelectDialog - MS Windows style file select dialog.
-    It provides an convenient method for the user to select files.
-
-    Subwidgets       Class
-    ----------       -----
-    fsbox       ExFileSelectBox"""
-
-    # FIXME: It should inherit -superclass tixDialogShell
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixExFileSelectDialog',
-                           ['options'], cnf, kw)
-        self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox')
-
-    def popup(self):
-        self.tk.call(self._w, 'popup')
-
-    def popdown(self):
-        self.tk.call(self._w, 'popdown')
-
-class FileSelectBox(TixWidget):
-    """ExFileSelectBox - Motif style file select box.
-    It is generally used for
-    the user to choose a file. FileSelectBox stores the files mostly
-    recently selected into a ComboBox widget so that they can be quickly
-    selected again.
-
-    Subwidget       Class
-    ---------       -----
-    selection       ComboBox
-    filter          ComboBox
-    dirlist         ScrolledListBox
-    filelist        ScrolledListBox"""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw)
-        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
-        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
-        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
-        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
-
-    def apply_filter(self):              # name of subwidget is same as command
-        self.tk.call(self._w, 'filter')
-
-    def invoke(self):
-        self.tk.call(self._w, 'invoke')
-
-# Should inherit from a Dialog class
-class FileSelectDialog(TixWidget):
-    """FileSelectDialog - Motif style file select dialog.
-
-    Subwidgets       Class
-    ----------       -----
-    btns       StdButtonBox
-    fsbox       FileSelectBox"""
-
-    # FIXME: It should inherit -superclass tixStdDialogShell
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixFileSelectDialog',
-                           ['options'], cnf, kw)
-        self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns')
-        self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox')
-
-    def popup(self):
-        self.tk.call(self._w, 'popup')
-
-    def popdown(self):
-        self.tk.call(self._w, 'popdown')
-
-class FileEntry(TixWidget):
-    """FileEntry - Entry field with button that invokes a FileSelectDialog.
-    The user can type in the filename manually. Alternatively, the user can
-    press the button widget that sits next to the entry, which will bring
-    up a file selection dialog.
-
-    Subwidgets       Class
-    ----------       -----
-    button       Button
-    entry       Entry"""
-
-    # FIXME: It should inherit -superclass tixLabelWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixFileEntry',
-                           ['dialogtype', 'options'], cnf, kw)
-        self.subwidget_list['button'] = _dummyButton(self, 'button')
-        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
-
-    def invoke(self):
-        self.tk.call(self._w, 'invoke')
-
-    def file_dialog(self):
-        # FIXME: return python object
-        pass
-
-class HList(TixWidget):
-    """HList - Hierarchy display  widget can be used to display any data
-    that have a hierarchical structure, for example, file system directory
-    trees. The list entries are indented and connected by branch lines
-    according to their places in the hierachy.
-
-    Subwidgets - None"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixHList',
-                           ['columns', 'options'], cnf, kw)
-
-    def add(self, entry, cnf={}, **kw):
-        return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw))
-
-    def add_child(self, parent=None, cnf={}, **kw):
-        if not parent:
-            parent = ''
-        return self.tk.call(
-                     self._w, 'addchild', parent, *self._options(cnf, kw))
-
-    def anchor_set(self, entry):
-        self.tk.call(self._w, 'anchor', 'set', entry)
-
-    def anchor_clear(self):
-        self.tk.call(self._w, 'anchor', 'clear')
-
-    def column_width(self, col=0, width=None, chars=None):
-        if not chars:
-            return self.tk.call(self._w, 'column', 'width', col, width)
-        else:
-            return self.tk.call(self._w, 'column', 'width', col,
-                                '-char', chars)
-
-    def delete_all(self):
-        self.tk.call(self._w, 'delete', 'all')
-
-    def delete_entry(self, entry):
-        self.tk.call(self._w, 'delete', 'entry', entry)
-
-    def delete_offsprings(self, entry):
-        self.tk.call(self._w, 'delete', 'offsprings', entry)
-
-    def delete_siblings(self, entry):
-        self.tk.call(self._w, 'delete', 'siblings', entry)
-
-    def dragsite_set(self, index):
-        self.tk.call(self._w, 'dragsite', 'set', index)
-
-    def dragsite_clear(self):
-        self.tk.call(self._w, 'dragsite', 'clear')
-
-    def dropsite_set(self, index):
-        self.tk.call(self._w, 'dropsite', 'set', index)
-
-    def dropsite_clear(self):
-        self.tk.call(self._w, 'dropsite', 'clear')
-
-    def header_create(self, col, cnf={}, **kw):
-        self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw))
-
-    def header_configure(self, col, cnf={}, **kw):
-        if cnf is None:
-            return _lst2dict(
-                self.tk.split(
-                self.tk.call(self._w, 'header', 'configure', col)))
-        self.tk.call(self._w, 'header', 'configure', col,
-                     *self._options(cnf, kw))
-
-    def header_cget(self,  col, opt):
-        return self.tk.call(self._w, 'header', 'cget', col, opt)
-
-    def header_exists(self,  col):
-        return self.tk.call(self._w, 'header', 'exists', col)
-
-    def header_delete(self, col):
-        self.tk.call(self._w, 'header', 'delete', col)
-
-    def header_size(self, col):
-        return self.tk.call(self._w, 'header', 'size', col)
-
-    def hide_entry(self, entry):
-        self.tk.call(self._w, 'hide', 'entry', entry)
-
-    def indicator_create(self, entry, cnf={}, **kw):
-        self.tk.call(
-              self._w, 'indicator', 'create', entry, *self._options(cnf, kw))
-
-    def indicator_configure(self, entry, cnf={}, **kw):
-        if cnf is None:
-            return _lst2dict(
-                self.tk.split(
-                self.tk.call(self._w, 'indicator', 'configure', entry)))
-        self.tk.call(
-              self._w, 'indicator', 'configure', entry, *self._options(cnf, kw))
-
-    def indicator_cget(self,  entry, opt):
-        return self.tk.call(self._w, 'indicator', 'cget', entry, opt)
-
-    def indicator_exists(self,  entry):
-        return self.tk.call (self._w, 'indicator', 'exists', entry)
-
-    def indicator_delete(self, entry):
-        self.tk.call(self._w, 'indicator', 'delete', entry)
-
-    def indicator_size(self, entry):
-        return self.tk.call(self._w, 'indicator', 'size', entry)
-
-    def info_anchor(self):
-        return self.tk.call(self._w, 'info', 'anchor')
-
-    def info_children(self, entry=None):
-        c = self.tk.call(self._w, 'info', 'children', entry)
-        return self.tk.splitlist(c)
-
-    def info_data(self, entry):
-        return self.tk.call(self._w, 'info', 'data', entry)
-
-    def info_exists(self, entry):
-        return self.tk.call(self._w, 'info', 'exists', entry)
-
-    def info_hidden(self, entry):
-        return self.tk.call(self._w, 'info', 'hidden', entry)
-
-    def info_next(self, entry):
-        return self.tk.call(self._w, 'info', 'next', entry)
-
-    def info_parent(self, entry):
-        return self.tk.call(self._w, 'info', 'parent', entry)
-
-    def info_prev(self, entry):
-        return self.tk.call(self._w, 'info', 'prev', entry)
-
-    def info_selection(self):
-        c = self.tk.call(self._w, 'info', 'selection')
-        return self.tk.splitlist(c)
-
-    def item_cget(self, entry, col, opt):
-        return self.tk.call(self._w, 'item', 'cget', entry, col, opt)
-
-    def item_configure(self, entry, col, cnf={}, **kw):
-        if cnf is None:
-            return _lst2dict(
-                self.tk.split(
-                self.tk.call(self._w, 'item', 'configure', entry, col)))
-        self.tk.call(self._w, 'item', 'configure', entry, col,
-              *self._options(cnf, kw))
-
-    def item_create(self, entry, col, cnf={}, **kw):
-        self.tk.call(
-              self._w, 'item', 'create', entry, col, *self._options(cnf, kw))
-
-    def item_exists(self, entry, col):
-        return self.tk.call(self._w, 'item', 'exists', entry, col)
-
-    def item_delete(self, entry, col):
-        self.tk.call(self._w, 'item', 'delete', entry, col)
-
-    def entrycget(self, entry, opt):
-        return self.tk.call(self._w, 'entrycget', entry, opt)
-
-    def entryconfigure(self, entry, cnf={}, **kw):
-        if cnf is None:
-            return _lst2dict(
-                self.tk.split(
-                self.tk.call(self._w, 'entryconfigure', entry)))
-        self.tk.call(self._w, 'entryconfigure', entry,
-              *self._options(cnf, kw))
-
-    def nearest(self, y):
-        return self.tk.call(self._w, 'nearest', y)
-
-    def see(self, entry):
-        self.tk.call(self._w, 'see', entry)
-
-    def selection_clear(self, cnf={}, **kw):
-        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
-
-    def selection_includes(self, entry):
-        return self.tk.call(self._w, 'selection', 'includes', entry)
-
-    def selection_set(self, first, last=None):
-        self.tk.call(self._w, 'selection', 'set', first, last)
-
-    def show_entry(self, entry):
-        return self.tk.call(self._w, 'show', 'entry', entry)
-
-    def xview(self, *args):
-        self.tk.call(self._w, 'xview', *args)
-
-    def yview(self, *args):
-        self.tk.call(self._w, 'yview', *args)
-
-class InputOnly(TixWidget):
-    """InputOnly - Invisible widget. Unix only.
-
-    Subwidgets - None"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw)
-
-class LabelEntry(TixWidget):
-    """LabelEntry - Entry field with label. Packages an entry widget
-    and a label into one mega widget. It can beused be used to simplify
-    the creation of ``entry-form'' type of interface.
-
-    Subwidgets       Class
-    ----------       -----
-    label       Label
-    entry       Entry"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixLabelEntry',
-                           ['labelside','options'], cnf, kw)
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
-
-class LabelFrame(TixWidget):
-    """LabelFrame - Labelled Frame container. Packages a frame widget
-    and a label into one mega widget. To create widgets inside a
-    LabelFrame widget, one creates the new widgets relative to the
-    frame subwidget and manage them inside the frame subwidget.
-
-    Subwidgets       Class
-    ----------       -----
-    label       Label
-    frame       Frame"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixLabelFrame',
-                           ['labelside','options'], cnf, kw)
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-        self.subwidget_list['frame'] = _dummyFrame(self, 'frame')
-
-
-class ListNoteBook(TixWidget):
-    """A ListNoteBook widget is very similar to the TixNoteBook widget:
-    it can be used to display many windows in a limited space using a
-    notebook metaphor. The notebook is divided into a stack of pages
-    (windows). At one time only one of these pages can be shown.
-    The user can navigate through these pages by
-    choosing the name of the desired page in the hlist subwidget."""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw)
-        # Is this necessary? It's not an exposed subwidget in Tix.
-        self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane',
-                                                        destroy_physically=0)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist')
-
-    def add(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
-        self.subwidget_list[name] = TixSubWidget(self, name)
-        return self.subwidget_list[name]
-
-    def page(self, name):
-        return self.subwidget(name)
-
-    def pages(self):
-        # Can't call subwidgets_all directly because we don't want .nbframe
-        names = self.tk.split(self.tk.call(self._w, 'pages'))
-        ret = []
-        for x in names:
-            ret.append(self.subwidget(x))
-        return ret
-
-    def raise_page(self, name):              # raise is a python keyword
-        self.tk.call(self._w, 'raise', name)
-
-class Meter(TixWidget):
-    """The Meter widget can be used to show the progress of a background
-    job which may take a long time to execute.
-    """
-
-    def __init__(self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixMeter',
-                           ['options'], cnf, kw)
-
-class NoteBook(TixWidget):
-    """NoteBook - Multi-page container widget (tabbed notebook metaphor).
-
-    Subwidgets       Class
-    ----------       -----
-    nbframe       NoteBookFrame
-    <pages>       page widgets added dynamically with the add method"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw)
-        self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe',
-                                                      destroy_physically=0)
-
-    def add(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
-        self.subwidget_list[name] = TixSubWidget(self, name)
-        return self.subwidget_list[name]
-
-    def delete(self, name):
-        self.tk.call(self._w, 'delete', name)
-        self.subwidget_list[name].destroy()
-        del self.subwidget_list[name]
-
-    def page(self, name):
-        return self.subwidget(name)
-
-    def pages(self):
-        # Can't call subwidgets_all directly because we don't want .nbframe
-        names = self.tk.split(self.tk.call(self._w, 'pages'))
-        ret = []
-        for x in names:
-            ret.append(self.subwidget(x))
-        return ret
-
-    def raise_page(self, name):              # raise is a python keyword
-        self.tk.call(self._w, 'raise', name)
-
-    def raised(self):
-        return self.tk.call(self._w, 'raised')
-
-class NoteBookFrame(TixWidget):
-    # FIXME: This is dangerous to expose to be called on its own.
-    pass
-
-class OptionMenu(TixWidget):
-    """OptionMenu - creates a menu button of options.
-
-    Subwidget       Class
-    ---------       -----
-    menubutton      Menubutton
-    menu            Menu"""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw)
-        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
-        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
-
-    def add_command(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw))
-
-    def add_separator(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw))
-
-    def delete(self, name):
-        self.tk.call(self._w, 'delete', name)
-
-    def disable(self, name):
-        self.tk.call(self._w, 'disable', name)
-
-    def enable(self, name):
-        self.tk.call(self._w, 'enable', name)
-
-class PanedWindow(TixWidget):
-    """PanedWindow - Multi-pane container widget
-    allows the user to interactively manipulate the sizes of several
-    panes. The panes can be arranged either vertically or horizontally.The
-    user changes the sizes of the panes by dragging the resize handle
-    between two panes.
-
-    Subwidgets       Class
-    ----------       -----
-    <panes>       g/p widgets added dynamically with the add method."""
-
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw)
-
-    # add delete forget panecget paneconfigure panes setsize
-    def add(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
-        self.subwidget_list[name] = TixSubWidget(self, name,
-                                                 check_intermediate=0)
-        return self.subwidget_list[name]
-
-    def delete(self, name):
-        self.tk.call(self._w, 'delete', name)
-        self.subwidget_list[name].destroy()
-        del self.subwidget_list[name]
-
-    def forget(self, name):
-        self.tk.call(self._w, 'forget', name)
-
-    def panecget(self,  entry, opt):
-        return self.tk.call(self._w, 'panecget', entry, opt)
-
-    def paneconfigure(self, entry, cnf={}, **kw):
-        if cnf is None:
-            return _lst2dict(
-                self.tk.split(
-                self.tk.call(self._w, 'paneconfigure', entry)))
-        self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
-
-    def panes(self):
-        names = self.tk.call(self._w, 'panes')
-        ret = []
-        for x in names:
-            ret.append(self.subwidget(x))
-        return ret
-
-class PopupMenu(TixWidget):
-    """PopupMenu widget can be used as a replacement of the tk_popup command.
-    The advantage of the Tix PopupMenu widget is it requires less application
-    code to manipulate.
-
-
-    Subwidgets       Class
-    ----------       -----
-    menubutton       Menubutton
-    menu       Menu"""
-
-    # FIXME: It should inherit -superclass tixShell
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw)
-        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
-        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
-
-    def bind_widget(self, widget):
-        self.tk.call(self._w, 'bind', widget._w)
-
-    def unbind_widget(self, widget):
-        self.tk.call(self._w, 'unbind', widget._w)
-
-    def post_widget(self, widget, x, y):
-        self.tk.call(self._w, 'post', widget._w, x, y)
-
-class ResizeHandle(TixWidget):
-    """Internal widget to draw resize handles on Scrolled widgets."""
-    def __init__(self, master, cnf={}, **kw):
-        # There seems to be a Tix bug rejecting the configure method
-        # Let's try making the flags -static
-        flags = ['options', 'command', 'cursorfg', 'cursorbg',
-                 'handlesize', 'hintcolor', 'hintwidth',
-                 'x', 'y']
-        # In fact, x y height width are configurable
-        TixWidget.__init__(self, master, 'tixResizeHandle',
-                           flags, cnf, kw)
-
-    def attach_widget(self, widget):
-        self.tk.call(self._w, 'attachwidget', widget._w)
-
-    def detach_widget(self, widget):
-        self.tk.call(self._w, 'detachwidget', widget._w)
-
-    def hide(self, widget):
-        self.tk.call(self._w, 'hide', widget._w)
-
-    def show(self, widget):
-        self.tk.call(self._w, 'show', widget._w)
-
-class ScrolledHList(TixWidget):
-    """ScrolledHList - HList with automatic scrollbars."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixScrolledHList', ['options'],
-                           cnf, kw)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class ScrolledListBox(TixWidget):
-    """ScrolledListBox - Listbox with automatic scrollbars."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw)
-        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class ScrolledText(TixWidget):
-    """ScrolledText - Text with automatic scrollbars."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw)
-        self.subwidget_list['text'] = _dummyText(self, 'text')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class ScrolledTList(TixWidget):
-    """ScrolledTList - TList with automatic scrollbars."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixScrolledTList', ['options'],
-                           cnf, kw)
-        self.subwidget_list['tlist'] = _dummyTList(self, 'tlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class ScrolledWindow(TixWidget):
-    """ScrolledWindow - Window with automatic scrollbars."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw)
-        self.subwidget_list['window'] = _dummyFrame(self, 'window')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class Select(TixWidget):
-    """Select - Container of button subwidgets. It can be used to provide
-    radio-box or check-box style of selection options for the user.
-
-    Subwidgets are buttons added dynamically using the add method."""
-
-    # FIXME: It should inherit -superclass tixLabelWidget
-    def __init__(self, master, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixSelect',
-                           ['allowzero', 'radio', 'orientation', 'labelside',
-                            'options'],
-                           cnf, kw)
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-
-    def add(self, name, cnf={}, **kw):
-        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
-        self.subwidget_list[name] = _dummyButton(self, name)
-        return self.subwidget_list[name]
-
-    def invoke(self, name):
-        self.tk.call(self._w, 'invoke', name)
-
-class Shell(TixWidget):
-    """Toplevel window.
-
-    Subwidgets - None"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw)
-
-class DialogShell(TixWidget):
-    """Toplevel window, with popup popdown and center methods.
-    It tells the window manager that it is a dialog window and should be
-    treated specially. The exact treatment depends on the treatment of
-    the window manager.
-
-    Subwidgets - None"""
-
-    # FIXME: It should inherit from  Shell
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master,
-                           'tixDialogShell',
-                           ['options', 'title', 'mapped',
-                            'minheight', 'minwidth',
-                            'parent', 'transient'], cnf, kw)
-
-    def popdown(self):
-        self.tk.call(self._w, 'popdown')
-
-    def popup(self):
-        self.tk.call(self._w, 'popup')
-
-    def center(self):
-        self.tk.call(self._w, 'center')
-
-class StdButtonBox(TixWidget):
-    """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """
-
-    def __init__(self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixStdButtonBox',
-                           ['orientation', 'options'], cnf, kw)
-        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
-        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
-        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
-        self.subwidget_list['help'] = _dummyButton(self, 'help')
-
-    def invoke(self, name):
-        if self.subwidget_list.has_key(name):
-            self.tk.call(self._w, 'invoke', name)
-
-class TList(TixWidget):
-    """TList - Hierarchy display widget which can be
-    used to display data in a tabular format. The list entries of a TList
-    widget are similar to the entries in the Tk listbox widget. The main
-    differences are (1) the TList widget can display the list entries in a
-    two dimensional format and (2) you can use graphical images as well as
-    multiple colors and fonts for the list entries.
-
-    Subwidgets - None"""
-
-    def __init__ (self,master=None,cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw)
-
-    def active_set(self, index):
-        self.tk.call(self._w, 'active', 'set', index)
-
-    def active_clear(self):
-        self.tk.call(self._w, 'active', 'clear')
-
-    def anchor_set(self, index):
-        self.tk.call(self._w, 'anchor', 'set', index)
-
-    def anchor_clear(self):
-        self.tk.call(self._w, 'anchor', 'clear')
-
-    def delete(self, from_, to=None):
-        self.tk.call(self._w, 'delete', from_, to)
-
-    def dragsite_set(self, index):
-        self.tk.call(self._w, 'dragsite', 'set', index)
-
-    def dragsite_clear(self):
-        self.tk.call(self._w, 'dragsite', 'clear')
-
-    def dropsite_set(self, index):
-        self.tk.call(self._w, 'dropsite', 'set', index)
-
-    def dropsite_clear(self):
-        self.tk.call(self._w, 'dropsite', 'clear')
-
-    def insert(self, index, cnf={}, **kw):
-        self.tk.call(self._w, 'insert', index, *self._options(cnf, kw))
-
-    def info_active(self):
-        return self.tk.call(self._w, 'info', 'active')
-
-    def info_anchor(self):
-        return self.tk.call(self._w, 'info', 'anchor')
-
-    def info_down(self, index):
-        return self.tk.call(self._w, 'info', 'down', index)
-
-    def info_left(self, index):
-        return self.tk.call(self._w, 'info', 'left', index)
-
-    def info_right(self, index):
-        return self.tk.call(self._w, 'info', 'right', index)
-
-    def info_selection(self):
-        c = self.tk.call(self._w, 'info', 'selection')
-        return self.tk.splitlist(c)
-
-    def info_size(self):
-        return self.tk.call(self._w, 'info', 'size')
-
-    def info_up(self, index):
-        return self.tk.call(self._w, 'info', 'up', index)
-
-    def nearest(self, x, y):
-        return self.tk.call(self._w, 'nearest', x, y)
-
-    def see(self, index):
-        self.tk.call(self._w, 'see', index)
-
-    def selection_clear(self, cnf={}, **kw):
-        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
-
-    def selection_includes(self, index):
-        return self.tk.call(self._w, 'selection', 'includes', index)
-
-    def selection_set(self, first, last=None):
-        self.tk.call(self._w, 'selection', 'set', first, last)
-
-    def xview(self, *args):
-        self.tk.call(self._w, 'xview', *args)
-
-    def yview(self, *args):
-        self.tk.call(self._w, 'yview', *args)
-
-class Tree(TixWidget):
-    """Tree - The tixTree widget can be used to display hierachical
-    data in a tree form. The user can adjust
-    the view of the tree by opening or closing parts of the tree."""
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixTree',
-                           ['options'], cnf, kw)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-    def autosetmode(self):
-        '''This command calls the setmode method for all the entries in this
-     Tree widget: if an entry has no child entries, its mode is set to
-     none. Otherwise, if the entry has any hidden child entries, its mode is
-     set to open; otherwise its mode is set to close.'''
-        self.tk.call(self._w, 'autosetmode')
-
-    def close(self, entrypath):
-        '''Close the entry given by entryPath if its mode is close.'''
-        self.tk.call(self._w, 'close', entrypath)
-
-    def getmode(self, entrypath):
-        '''Returns the current mode of the entry given by entryPath.'''
-        return self.tk.call(self._w, 'getmode', entrypath)
-
-    def open(self, entrypath):
-        '''Open the entry given by entryPath if its mode is open.'''
-        self.tk.call(self._w, 'open', entrypath)
-
-    def setmode(self, entrypath, mode='none'):
-        '''This command is used to indicate whether the entry given by
-     entryPath has children entries and whether the children are visible. mode
-     must be one of open, close or none. If mode is set to open, a (+)
-     indicator is drawn next the the entry. If mode is set to close, a (-)
-     indicator is drawn next the the entry. If mode is set to none, no
-     indicators will be drawn for this entry. The default mode is none. The
-     open mode indicates the entry has hidden children and this entry can be
-     opened by the user. The close mode indicates that all the children of the
-     entry are now visible and the entry can be closed by the user.'''
-        self.tk.call(self._w, 'setmode', entrypath, mode)
-
-
-# Could try subclassing Tree for CheckList - would need another arg to init
-class CheckList(TixWidget):
-    """The CheckList widget
-    displays a list of items to be selected by the user. CheckList acts
-    similarly to the Tk checkbutton or radiobutton widgets, except it is
-    capable of handling many more items than checkbuttons or radiobuttons.
-    """
-    # FIXME: It should inherit -superclass tixTree
-    def __init__(self, master=None, cnf={}, **kw):
-        TixWidget.__init__(self, master, 'tixCheckList',
-                           ['options'], cnf, kw)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-    def autosetmode(self):
-        '''This command calls the setmode method for all the entries in this
-     Tree widget: if an entry has no child entries, its mode is set to
-     none. Otherwise, if the entry has any hidden child entries, its mode is
-     set to open; otherwise its mode is set to close.'''
-        self.tk.call(self._w, 'autosetmode')
-
-    def close(self, entrypath):
-        '''Close the entry given by entryPath if its mode is close.'''
-        self.tk.call(self._w, 'close', entrypath)
-
-    def getmode(self, entrypath):
-        '''Returns the current mode of the entry given by entryPath.'''
-        return self.tk.call(self._w, 'getmode', entrypath)
-
-    def open(self, entrypath):
-        '''Open the entry given by entryPath if its mode is open.'''
-        self.tk.call(self._w, 'open', entrypath)
-
-    def getselection(self, mode='on'):
-        '''Returns a list of items whose status matches status. If status is
-     not specified, the list of items in the "on" status will be returned.
-     Mode can be on, off, default'''
-        c = self.tk.split(self.tk.call(self._w, 'getselection', mode))
-        return self.tk.splitlist(c)
-
-    def getstatus(self, entrypath):
-        '''Returns the current status of entryPath.'''
-        return self.tk.call(self._w, 'getstatus', entrypath)
-
-    def setstatus(self, entrypath, mode='on'):
-        '''Sets the status of entryPath to be status. A bitmap will be
-     displayed next to the entry its status is on, off or default.'''
-        self.tk.call(self._w, 'setstatus', entrypath, mode)
-
-
-###########################################################################
-### The subclassing below is used to instantiate the subwidgets in each ###
-### mega widget. This allows us to access their methods directly.       ###
-###########################################################################
-
-class _dummyButton(Button, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyCheckbutton(Checkbutton, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyEntry(Entry, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyFrame(Frame, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyLabel(Label, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyListbox(Listbox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyMenu(Menu, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyMenubutton(Menubutton, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyScrollbar(Scrollbar, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyText(Text, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyScrolledListBox(ScrolledListBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class _dummyHList(HList, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyScrolledHList(ScrolledHList, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class _dummyTList(TList, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyComboBox(ComboBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically])
-        self.subwidget_list['label'] = _dummyLabel(self, 'label')
-        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
-        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
-
-        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
-                                                                'slistbox')
-        try:
-            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
-            #cross Button : present if created with the fancy option
-            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
-        except TypeError:
-            # unavailable when -fancy not specified
-            pass
-
-class _dummyDirList(DirList, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
-        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
-        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
-
-class _dummyDirSelectBox(DirSelectBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
-        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
-
-class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
-        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
-        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
-        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
-        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
-        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
-        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
-        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
-
-class _dummyFileSelectBox(FileSelectBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
-        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
-        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
-        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
-
-class _dummyFileComboBox(ComboBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx')
-
-class _dummyStdButtonBox(StdButtonBox, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
-        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
-        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
-        self.subwidget_list['help'] = _dummyButton(self, 'help')
-
-class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=0):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-class _dummyPanedWindow(PanedWindow, TixSubWidget):
-    def __init__(self, master, name, destroy_physically=1):
-        TixSubWidget.__init__(self, master, name, destroy_physically)
-
-########################
-### Utility Routines ###
-########################
-
-#mike Should tixDestroy be exposed as a wrapper? - but not for widgets.
-
-def OptionName(widget):
-    '''Returns the qualified path name for the widget. Normally used to set
-    default options for subwidgets. See tixwidgets.py'''
-    return widget.tk.call('tixOptionName', widget._w)
-
-# Called with a dictionary argument of the form
-# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'}
-# returns a string which can be used to configure the fsbox file types
-# in an ExFileSelectBox. i.e.,
-# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}'
-def FileTypeList(dict):
-    s = ''
-    for type in dict.keys():
-        s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} '
-    return s
-
-# Still to be done:
-# tixIconView
-class CObjView(TixWidget):
-    """This file implements the Canvas Object View widget. This is a base
-    class of IconView. It implements automatic placement/adjustment of the
-    scrollbars according to the canvas objects inside the canvas subwidget.
-    The scrollbars are adjusted so that the canvas is just large enough
-    to see all the objects.
-    """
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    pass
-
-
-class Grid(TixWidget):
-    '''The Tix Grid command creates a new window  and makes it into a
-    tixGrid widget. Additional options, may be specified on the command
-    line or in the option database to configure aspects such as its cursor
-    and relief.
-
-    A Grid widget displays its contents in a two dimensional grid of cells.
-    Each cell may contain one Tix display item, which may be in text,
-    graphics or other formats. See the DisplayStyle class for more information
-    about Tix display items. Individual cells, or groups of cells, can be
-    formatted with a wide range of attributes, such as its color, relief and
-    border.
-
-    Subwidgets - None'''
-    # valid specific resources as of Tk 8.4
-    # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd,
-    # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode,
-    # selectunit, topmargin,
-    def __init__(self, master=None, cnf={}, **kw):
-        static= []
-        self.cnf= cnf
-        TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw)
-
-    # valid options as of Tk 8.4
-    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, edit
-    # entryconfigure, format, geometryinfo, info, index, move, nearest, selection
-    # set, size, unset, xview, yview
-    # def anchor option ?args ...?
-    def anchor_get(self):
-        "Get the (x,y) coordinate of the current anchor cell"
-        return self._getints(self.tk.call(self, 'anchor', 'get'))
-
-    # def bdtype
-    # def delete dim from ?to?
-    def delete_row(self, from_, to=None):
-        """Delete rows between from_ and to inclusive.
-        If to is not provided,  delete only row at from_"""
-        if to is None:
-            self.tk.call(self, 'delete', 'row', from_)
-        else:
-            self.tk.call(self, 'delete', 'row', from_, to)
-    def delete_column(self, from_, to=None):
-        """Delete columns between from_ and to inclusive.
-        If to is not provided,  delete only column at from_"""
-        if to is None:
-            self.tk.call(self, 'delete', 'column', from_)
-        else:
-            self.tk.call(self, 'delete', 'column', from_, to)
-    # def edit apply
-    # def edit set x y
-
-    def entrycget(self, x, y, option):
-        "Get the option value for cell at (x,y)"
-        return self.tk.call(self, 'entrycget', x, y, option)
-
-    def entryconfigure(self, x, y, **kw):
-        return self.tk.call(self, 'entryconfigure', x, y, *self._options(None, kw))
-    # def format
-    # def index
-
-    def info_exists(self, x, y):
-        "Return True if display item exists at (x,y)"
-        return bool(int(self.tk.call(self, 'info', 'exists', x, y)))
-
-    def info_bbox(self, x, y):
-        # This seems to always return '', at least for 'text' displayitems
-        return self.tk.call(self, 'info', 'bbox', x, y)
-
-    def nearest(self, x, y):
-        "Return coordinate of cell nearest pixel coordinate (x,y)"
-        return self._getints(self.tk.call(self, 'nearest', x, y))
-
-    # def selection adjust
-    # def selection clear
-    # def selection includes
-    # def selection set
-    # def selection toggle
-    # def move dim from to offset
-
-    def set(self, x, y, itemtype=None, **kw):
-        args= self._options(self.cnf, kw)
-        if itemtype is not None:
-            args= ('-itemtype', itemtype) + args
-        self.tk.call(self, 'set', x, y, *args)
-
-    # def size dim index ?option value ...?
-    # def unset x y
-
-    def xview(self):
-        return self._getdoubles(self.tk.call(self, 'xview'))
-    def xview_moveto(self, fraction):
-        self.tk.call(self,'xview', 'moveto', fraction)
-    def xview_scroll(self, count, what="units"):
-        "Scroll right (count>0) or left <count> of units|pages"
-        self.tk.call(self, 'xview', 'scroll', count, what)
-
-    def yview(self):
-        return self._getdoubles(self.tk.call(self, 'yview'))
-    def yview_moveto(self, fraction):
-        self.tk.call(self,'ysview', 'moveto', fraction)
-    def yview_scroll(self, count, what="units"):
-        "Scroll down (count>0) or up <count> of units|pages"
-        self.tk.call(self, 'yview', 'scroll', count, what)
-
-class ScrolledGrid(Grid):
-    '''Scrolled Grid widgets'''
-
-    # FIXME: It should inherit -superclass tixScrolledWidget
-    def __init__(self, master=None, cnf={}, **kw):
-        static= []
-        self.cnf= cnf
-        TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw)
diff --git a/Lib/tkinter/turtle.py b/Lib/tkinter/turtle.py
deleted file mode 100644
index 0d343e6..0000000
--- a/Lib/tkinter/turtle.py
+++ /dev/null
@@ -1,956 +0,0 @@
-# LogoMation-like turtle graphics
-
-"""
-Turtle graphics is a popular way for introducing programming to
-kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
-
-Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
-the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
-the direction it is facing, drawing a line as it moves. Give it the
-command turtle.left(25), and it rotates in-place 25 degrees clockwise.
-
-By combining together these and similar commands, intricate shapes and
-pictures can easily be drawn.
-"""
-
-from math import * # Also for export
-from time import sleep
-import tkinter
-
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
-
-class Error(Exception):
-    pass
-
-class RawPen:
-
-    def __init__(self, canvas):
-        self._canvas = canvas
-        self._items = []
-        self._tracing = 1
-        self._arrow = 0
-        self._delay = 10     # default delay for drawing
-        self._angle = 0.0
-        self.degrees()
-        self.reset()
-
-    def degrees(self, fullcircle=360.0):
-        """ Set angle measurement units to degrees.
-
-        Example:
-        >>> turtle.degrees()
-        """
-        # Don't try to change _angle if it is 0, because
-        # _fullcircle might not be set, yet
-        if self._angle:
-            self._angle = (self._angle / self._fullcircle) * fullcircle
-        self._fullcircle = fullcircle
-        self._invradian = pi / (fullcircle * 0.5)
-
-    def radians(self):
-        """ Set the angle measurement units to radians.
-
-        Example:
-        >>> turtle.radians()
-        """
-        self.degrees(2.0*pi)
-
-    def reset(self):
-        """ Clear the screen, re-center the pen, and set variables to
-        the default values.
-
-        Example:
-        >>> turtle.position()
-        [0.0, -22.0]
-        >>> turtle.heading()
-        100.0
-        >>> turtle.reset()
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.heading()
-        0.0
-        """
-        canvas = self._canvas
-        self._canvas.update()
-        width = canvas.winfo_width()
-        height = canvas.winfo_height()
-        if width <= 1:
-            width = canvas['width']
-        if height <= 1:
-            height = canvas['height']
-        self._origin = float(width)/2.0, float(height)/2.0
-        self._position = self._origin
-        self._angle = 0.0
-        self._drawing = 1
-        self._width = 1
-        self._color = "black"
-        self._filling = 0
-        self._path = []
-        self.clear()
-        canvas._root().tkraise()
-
-    def clear(self):
-        """ Clear the screen. The turtle does not move.
-
-        Example:
-        >>> turtle.clear()
-        """
-        self.fill(0)
-        canvas = self._canvas
-        items = self._items
-        self._items = []
-        for item in items:
-            canvas.delete(item)
-        self._delete_turtle()
-        self._draw_turtle()
-
-    def tracer(self, flag):
-        """ Set tracing on if flag is True, and off if it is False.
-        Tracing means line are drawn more slowly, with an
-        animation of an arrow along the line.
-
-        Example:
-        >>> turtle.tracer(False)   # turns off Tracer
-        """
-        self._tracing = flag
-        if not self._tracing:
-            self._delete_turtle()
-        self._draw_turtle()
-
-    def forward(self, distance):
-        """ Go forward distance steps.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.forward(25)
-        >>> turtle.position()
-        [25.0, 0.0]
-        >>> turtle.forward(-75)
-        >>> turtle.position()
-        [-50.0, 0.0]
-        """
-        x0, y0 = start = self._position
-        x1 = x0 + distance * cos(self._angle*self._invradian)
-        y1 = y0 - distance * sin(self._angle*self._invradian)
-        self._goto(x1, y1)
-
-    def backward(self, distance):
-        """ Go backwards distance steps.
-
-        The turtle's heading does not change.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.backward(30)
-        >>> turtle.position()
-        [-30.0, 0.0]
-        """
-        self.forward(-distance)
-
-    def left(self, angle):
-        """ Turn left angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
-
-        When viewed from above, the turning happens in-place around
-        its front tip.
-
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.left(45)
-        >>> turtle.heading()
-        67.0
-        """
-        self._angle = (self._angle + angle) % self._fullcircle
-        self._draw_turtle()
-
-    def right(self, angle):
-        """ Turn right angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
-
-        When viewed from above, the turning happens in-place around
-        its front tip.
-
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.right(45)
-        >>> turtle.heading()
-        337.0
-        """
-        self.left(-angle)
-
-    def up(self):
-        """ Pull the pen up -- no drawing when moving.
-
-        Example:
-        >>> turtle.up()
-        """
-        self._drawing = 0
-
-    def down(self):
-        """ Put the pen down -- draw when moving.
-
-        Example:
-        >>> turtle.down()
-        """
-        self._drawing = 1
-
-    def width(self, width):
-        """ Set the line to thickness to width.
-
-        Example:
-        >>> turtle.width(10)
-        """
-        self._width = float(width)
-
-    def color(self, *args):
-        """ Set the pen color.
-
-        Three input formats are allowed:
-
-            color(s)
-            s is a Tk specification string, such as "red" or "yellow"
-
-            color((r, g, b))
-            *a tuple* of r, g, and b, which represent, an RGB color,
-            and each of r, g, and b are in the range [0..1]
-
-            color(r, g, b)
-            r, g, and b represent an RGB color, and each of r, g, and b
-            are in the range [0..1]
-
-        Example:
-
-        >>> turtle.color('brown')
-        >>> tup = (0.2, 0.8, 0.55)
-        >>> turtle.color(tup)
-        >>> turtle.color(0, .5, 0)
-        """
-        if not args:
-            raise Error, "no color arguments"
-        if len(args) == 1:
-            color = args[0]
-            if type(color) == type(""):
-                # Test the color first
-                try:
-                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
-                except tkinter.TclError:
-                    raise Error, "bad color string: %r" % (color,)
-                self._set_color(color)
-                return
-            try:
-                r, g, b = color
-            except:
-                raise Error, "bad color sequence: %r" % (color,)
-        else:
-            try:
-                r, g, b = args
-            except:
-                raise Error, "bad color arguments: %r" % (args,)
-        assert 0 <= r <= 1
-        assert 0 <= g <= 1
-        assert 0 <= b <= 1
-        x = 255.0
-        y = 0.5
-        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
-
-    def _set_color(self,color):
-        self._color = color
-        self._draw_turtle()
-
-    def write(self, text, move=False):
-        """ Write text at the current pen position.
-
-        If move is true, the pen is moved to the bottom-right corner
-        of the text. By default, move is False.
-
-        Example:
-        >>> turtle.write('The race is on!')
-        >>> turtle.write('Home = (0, 0)', True)
-        """
-        x, y  = self._position
-        x = x-1 # correction -- calibrated for Windows
-        item = self._canvas.create_text(x, y,
-                                        text=str(text), anchor="sw",
-                                        fill=self._color)
-        self._items.append(item)
-        if move:
-            x0, y0, x1, y1 = self._canvas.bbox(item)
-            self._goto(x1, y1)
-        self._draw_turtle()
-
-    def fill(self, flag):
-        """ Call fill(1) before drawing the shape you
-         want to fill, and fill(0) when done.
-
-        Example:
-        >>> turtle.fill(1)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.fill(0)
-        """
-        if self._filling:
-            path = tuple(self._path)
-            smooth = self._filling < 0
-            if len(path) > 2:
-                item = self._canvas._create('polygon', path,
-                                            {'fill': self._color,
-                                             'smooth': smooth})
-                self._items.append(item)
-        self._path = []
-        self._filling = flag
-        if flag:
-            self._path.append(self._position)
-
-    def begin_fill(self):
-        """ Called just before drawing a shape to be filled.
-            Must eventually be followed by a corresponding end_fill() call.
-            Otherwise it will be ignored.
-
-        Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
-        """
-        self._path = [self._position]
-        self._filling = 1
-
-    def end_fill(self):
-        """ Called after drawing a shape to be filled.
-
-        Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
-        """
-        self.fill(0)
-
-    def circle(self, radius, extent = None):
-        """ Draw a circle with given radius.
-        The center is radius units left of the turtle; extent
-        determines which part of the circle is drawn. If not given,
-        the entire circle is drawn.
-
-        If extent is not a full circle, one endpoint of the arc is the
-        current pen position. The arc is drawn in a counter clockwise
-        direction if radius is positive, otherwise in a clockwise
-        direction. In the process, the direction of the turtle is
-        changed by the amount of the extent.
-
-        >>> turtle.circle(50)
-        >>> turtle.circle(120, 180)  # half a circle
-        """
-        if extent is None:
-            extent = self._fullcircle
-        frac = abs(extent)/self._fullcircle
-        steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
-        w = 1.0 * extent / steps
-        w2 = 0.5 * w
-        l = 2.0 * radius * sin(w2*self._invradian)
-        if radius < 0:
-            l, w, w2 = -l, -w, -w2
-        self.left(w2)
-        for i in range(steps):
-            self.forward(l)
-            self.left(w)
-        self.right(w2)
-
-    def heading(self):
-        """ Return the turtle's current heading.
-
-        Example:
-        >>> turtle.heading()
-        67.0
-        """
-        return self._angle
-
-    def setheading(self, angle):
-        """ Set the turtle facing the given angle.
-
-        Here are some common directions in degrees:
-
-           0 - east
-          90 - north
-         180 - west
-         270 - south
-
-        Example:
-        >>> turtle.setheading(90)
-        >>> turtle.heading()
-        90
-        >>> turtle.setheading(128)
-        >>> turtle.heading()
-        128
-        """
-        self._angle = angle
-        self._draw_turtle()
-
-    def window_width(self):
-        """ Returns the width of the turtle window.
-
-        Example:
-        >>> turtle.window_width()
-        640
-        """
-        width = self._canvas.winfo_width()
-        if width <= 1:  # the window isn't managed by a geometry manager
-            width = self._canvas['width']
-        return width
-
-    def window_height(self):
-        """ Return the height of the turtle window.
-
-        Example:
-        >>> turtle.window_height()
-        768
-        """
-        height = self._canvas.winfo_height()
-        if height <= 1: # the window isn't managed by a geometry manager
-            height = self._canvas['height']
-        return height
-
-    def position(self):
-        """ Return the current (x, y) location of the turtle.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 240.0]
-        """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        return [x1-x0, -y1+y0]
-
-    def setx(self, xpos):
-        """ Set the turtle's x coordinate to be xpos.
-
-        Example:
-        >>> turtle.position()
-        [10.0, 240.0]
-        >>> turtle.setx(10)
-        >>> turtle.position()
-        [10.0, 240.0]
-        """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x0+xpos, y1)
-
-    def sety(self, ypos):
-        """ Set the turtle's y coordinate to be ypos.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.sety(-22)
-        >>> turtle.position()
-        [0.0, -22.0]
-        """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x1, y0-ypos)
-
-    def towards(self, *args):
-        """Returs the angle, which corresponds to the line
-        from turtle-position to point (x,y).
-
-        Argument can be two coordinates or one pair of coordinates
-        or a RawPen/Pen instance.
-
-        Example:
-        >>> turtle.position()
-        [10.0, 10.0]
-        >>> turtle.towards(0,0)
-        225.0
-        """
-        if len(args) == 2:
-            x, y = args
-        else:
-            arg = args[0]
-            if isinstance(arg, RawPen):
-                x, y = arg.position()
-            else:
-                x, y = arg
-        x0, y0 = self.position()
-        dx = x - x0
-        dy = y - y0
-        return (atan2(dy,dx) / self._invradian) % self._fullcircle
-
-    def goto(self, *args):
-        """ Go to the given point.
-
-        If the pen is down, then a line will be drawn. The turtle's
-        orientation does not change.
-
-        Two input formats are accepted:
-
-           goto(x, y)
-           go to point (x, y)
-
-           goto((x, y))
-           go to point (x, y)
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.goto(50, -45)
-        >>> turtle.position()
-        [50.0, -45.0]
-        """
-        if len(args) == 1:
-            try:
-                x, y = args[0]
-            except:
-                raise Error, "bad point argument: %r" % (args[0],)
-        else:
-            try:
-                x, y = args
-            except:
-                raise Error, "bad coordinates: %r" % (args[0],)
-        x0, y0 = self._origin
-        self._goto(x0+x, y0-y)
-
-    def _goto(self, x1, y1):
-        x0, y0 = self._position
-        self._position = map(float, (x1, y1))
-        if self._filling:
-            self._path.append(self._position)
-        if self._drawing:
-            if self._tracing:
-                dx = float(x1 - x0)
-                dy = float(y1 - y0)
-                distance = hypot(dx, dy)
-                nhops = int(distance)
-                item = self._canvas.create_line(x0, y0, x0, y0,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-                try:
-                    for i in range(1, 1+nhops):
-                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
-                        self._canvas.coords(item, x0, y0, x, y)
-                        self._draw_turtle((x,y))
-                        self._canvas.update()
-                        self._canvas.after(self._delay)
-                    # in case nhops==0
-                    self._canvas.coords(item, x0, y0, x1, y1)
-                    self._canvas.itemconfigure(item, arrow="none")
-                except tkinter.TclError:
-                    # Probably the window was closed!
-                    return
-            else:
-                item = self._canvas.create_line(x0, y0, x1, y1,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-            self._items.append(item)
-        self._draw_turtle()
-
-    def speed(self, speed):
-        """ Set the turtle's speed.
-
-        speed must one of these five strings:
-
-            'fastest' is a 0 ms delay
-            'fast' is a 5 ms delay
-            'normal' is a 10 ms delay
-            'slow' is a 15 ms delay
-            'slowest' is a 20 ms delay
-
-         Example:
-         >>> turtle.speed('slow')
-        """
-        try:
-            speed = speed.strip().lower()
-            self._delay = speeds.index(speed) * 5
-        except:
-            raise ValueError("%r is not a valid speed. speed must be "
-                             "one of %s" % (speed, speeds))
-
-
-    def delay(self, delay):
-        """ Set the drawing delay in milliseconds.
-
-        This is intended to allow finer control of the drawing speed
-        than the speed() method
-
-        Example:
-        >>> turtle.delay(15)
-        """
-        if int(delay) < 0:
-            raise ValueError("delay must be greater than or equal to 0")
-        self._delay = int(delay)
-
-    def _draw_turtle(self, position=[]):
-        if not self._tracing:
-            self._canvas.update()
-            return
-        if position == []:
-            position = self._position
-        x,y = position
-        distance = 8
-        dx = distance * cos(self._angle*self._invradian)
-        dy = distance * sin(self._angle*self._invradian)
-        self._delete_turtle()
-        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
-                                          width=self._width,
-                                          arrow="last",
-                                          capstyle="round",
-                                          fill=self._color)
-        self._canvas.update()
-
-    def _delete_turtle(self):
-        if self._arrow != 0:
-            self._canvas.delete(self._arrow)
-            self._arrow = 0
-
-
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50                  # 50% of window width
-_height = 0.75                 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics"     # default title
-
-class Pen(RawPen):
-
-    def __init__(self):
-        global _root, _canvas
-        if _root is None:
-            _root = tkinter.Tk()
-            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
-            _root.title(_title)
-
-        if _canvas is None:
-            # XXX Should have scroll bars
-            _canvas = tkinter.Canvas(_root, background="white")
-            _canvas.pack(expand=1, fill="both")
-
-            setup(width=_width, height= _height, startx=_startx, starty=_starty)
-
-        RawPen.__init__(self, _canvas)
-
-    def _destroy(self):
-        global _root, _canvas, _pen
-        root = self._canvas._root()
-        if root is _root:
-            _pen = None
-            _root = None
-            _canvas = None
-        root.destroy()
-
-def _getpen():
-    global _pen
-    if not _pen:
-        _pen = Pen()
-    return _pen
-
-class Turtle(Pen):
-    pass
-
-"""For documentation of the following functions see
-   the RawPen methods with the same names
-"""
-
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
-
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
-    """ copies RawPen docstrings to module functions of same name """
-    if not methodname.startswith("_"):
-        eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
-    """ Sets the size and position of the main window.
-
-    Keywords are width, height, startx and starty:
-
-    width: either a size in pixels or a fraction of the screen.
-      Default is 50% of screen.
-    height: either the height in pixels or a fraction of the screen.
-      Default is 75% of screen.
-
-    Setting either width or height to None before drawing will force
-      use of default geometry as in older versions of turtle.py
-
-    startx: starting position in pixels from the left edge of the screen.
-      Default is to center window. Setting startx to None is the default
-      and centers window horizontally on screen.
-
-    starty: starting position in pixels from the top edge of the screen.
-      Default is to center window. Setting starty to None is the default
-      and centers window vertically on screen.
-
-    Examples:
-    >>> setup (width=200, height=200, startx=0, starty=0)
-
-    sets window to 200x200 pixels, in upper left of screen
-
-    >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
-    sets window to 75% of screen by 50% of screen and centers
-
-    >>> setup(width=None)
-
-    forces use of default geometry as in older versions of turtle.py
-    """
-
-    global _width, _height, _startx, _starty
-
-    width = geometry.get('width',_width)
-    if width >= 0 or width is None:
-        _width = width
-    else:
-        raise ValueError, "width can not be less than 0"
-
-    height = geometry.get('height',_height)
-    if height >= 0 or height is None:
-        _height = height
-    else:
-        raise ValueError, "height can not be less than 0"
-
-    startx = geometry.get('startx', _startx)
-    if startx >= 0 or startx is None:
-        _startx = _startx
-    else:
-        raise ValueError, "startx can not be less than 0"
-
-    starty = geometry.get('starty', _starty)
-    if starty >= 0 or starty is None:
-        _starty = starty
-    else:
-        raise ValueError, "startx can not be less than 0"
-
-
-    if _root and _width and _height:
-        if 0 < _width <= 1:
-            _width = _root.winfo_screenwidth() * +width
-        if 0 < _height <= 1:
-            _height = _root.winfo_screenheight() * _height
-
-        # center window on screen
-        if _startx is None:
-            _startx = (_root.winfo_screenwidth() - _width) / 2
-
-        if _starty is None:
-            _starty = (_root.winfo_screenheight() - _height) / 2
-
-        _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
-
-def title(title):
-    """Set the window title.
-
-    By default this is set to 'Turtle Graphics'
-
-    Example:
-    >>> title("My Window")
-    """
-
-    global _title
-    _title = title
-
-def demo():
-    reset()
-    tracer(1)
-    up()
-    backward(100)
-    down()
-    # draw 3 squares; the last filled
-    width(3)
-    for i in range(3):
-        if i == 2:
-            fill(1)
-        for j in range(4):
-            forward(20)
-            left(90)
-        if i == 2:
-            color("maroon")
-            fill(0)
-        up()
-        forward(30)
-        down()
-    width(1)
-    color("black")
-    # move out of the way
-    tracer(0)
-    up()
-    right(90)
-    forward(100)
-    right(90)
-    forward(100)
-    right(180)
-    down()
-    # some text
-    write("startstart", 1)
-    write("start", 1)
-    color("red")
-    # staircase
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    # filled staircase
-    fill(1)
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    fill(0)
-    tracer(1)
-    # more text
-    write("end")
-
-def demo2():
-    # exercises some new and improved features
-    speed('fast')
-    width(3)
-
-    # draw a segmented half-circle
-    setheading(towards(0,0))
-    x,y = position()
-    r = (x**2+y**2)**.5/2.0
-    right(90)
-    pendown = True
-    for i in range(18):
-        if pendown:
-            up()
-            pendown = False
-        else:
-            down()
-            pendown = True
-        circle(r,10)
-    sleep(2)
-
-    reset()
-    left(90)
-
-    # draw a series of triangles
-    l = 10
-    color("green")
-    width(3)
-    left(180)
-    sp = 5
-    for i in range(-2,16):
-        if i > 0:
-            color(1.0-0.05*i,0,0.05*i)
-            fill(1)
-            color("green")
-        for j in range(3):
-            forward(l)
-            left(120)
-        l += 10
-        left(15)
-        if sp > 0:
-            sp = sp-1
-            speed(speeds[sp])
-    color(0.25,0,0.75)
-    fill(0)
-
-    # draw and fill a concave shape
-    left(120)
-    up()
-    forward(70)
-    right(30)
-    down()
-    color("red")
-    speed("fastest")
-    fill(1)
-    for i in range(4):
-        circle(50,90)
-        right(90)
-        forward(30)
-        right(90)
-    color("yellow")
-    fill(0)
-    left(90)
-    up()
-    forward(30)
-    down();
-
-    color("red")
-
-    # create a second turtle and make the original pursue and catch it
-    turtle=Turtle()
-    turtle.reset()
-    turtle.left(90)
-    turtle.speed('normal')
-    turtle.up()
-    turtle.goto(280,40)
-    turtle.left(24)
-    turtle.down()
-    turtle.speed('fast')
-    turtle.color("blue")
-    turtle.width(2)
-    speed('fastest')
-
-    # turn default turtle towards new turtle object
-    setheading(towards(turtle))
-    while ( abs(position()[0]-turtle.position()[0])>4 or
-            abs(position()[1]-turtle.position()[1])>4):
-        turtle.forward(3.5)
-        turtle.left(0.6)
-        # turn default turtle towards new turtle object
-        setheading(towards(turtle))
-        forward(4)
-    write("CAUGHT! ", move=True)
-
-
-
-if __name__ == '__main__':
-    demo()
-    sleep(3)
-    demo2()
-    done()
