diff --git a/Lib/compiler/transformer.py b/Lib/compiler/transformer.py
index 9038f7e..9074fc7 100644
--- a/Lib/compiler/transformer.py
+++ b/Lib/compiler/transformer.py
@@ -72,7 +72,7 @@
     kind = args[0]
     if nodes.has_key(kind):
         try:
-            return apply(nodes[kind], args[1:])
+            return nodes[kind](*args[1:])
         except TypeError:
             print nodes[kind], len(args), args
             raise
diff --git a/Lib/curses/wrapper.py b/Lib/curses/wrapper.py
index e725c5a..b8905fb 100644
--- a/Lib/curses/wrapper.py
+++ b/Lib/curses/wrapper.py
@@ -41,7 +41,7 @@
         except:
             pass
 
-        res = apply(func, (stdscr,) + rest)
+        res = func(stdscr, *rest)
     except:
         # In the event of an error, restore the terminal
         # to a sane state.
diff --git a/Lib/lib-tk/Canvas.py b/Lib/lib-tk/Canvas.py
index ae2ced1..83d7bba 100644
--- a/Lib/lib-tk/Canvas.py
+++ b/Lib/lib-tk/Canvas.py
@@ -55,7 +55,7 @@
     def coords(self, pts = ()):
         flat = ()
         for x, y in pts: flat = flat + (x, y)
-        return apply(self.canvas.coords, (self.id,) + flat)
+        return self.canvas.coords(self.id, *flat)
     def dchars(self, first, last=None):
         self.canvas.dchars(self.id, first, last)
     def dtag(self, ttd):
@@ -84,40 +84,40 @@
 
 class Arc(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'arc') + args, kw)
+        CanvasItem.__init__(self, canvas, 'arc', *args, **kw)
 
 class Bitmap(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'bitmap') + args, kw)
+        CanvasItem.__init__(self, canvas, 'bitmap', *args, **kw)
 
 class ImageItem(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'image') + args, kw)
+        CanvasItem.__init__(self, canvas, 'image', *args, **kw)
 
 class Line(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'line') + args, kw)
+        CanvasItem.__init__(self, canvas, 'line', *args, **kw)
 
 class Oval(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'oval') + args, kw)
+        CanvasItem.__init__(self, canvas, 'oval', *args, **kw)
 
 class Polygon(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'polygon') + args,kw)
+        CanvasItem.__init__(self, canvas, 'polygon', *args, **kw)
 
 class Rectangle(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'rectangle')+args,kw)
+        CanvasItem.__init__(self, canvas, 'rectangle', *args, **kw)
 
 # XXX "Text" is taken by the Text widget...
 class CanvasText(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'text') + args, kw)
+        CanvasItem.__init__(self, canvas, 'text', *args, **kw)
 
 class Window(CanvasItem):
     def __init__(self, canvas, *args, **kw):
-        apply(CanvasItem.__init__, (self, canvas, 'window') + args, kw)
+        CanvasItem.__init__(self, canvas, 'window', *args, **kw)
 
 class Group:
     def __init__(self, canvas, tag=None):
diff --git a/Lib/lib-tk/Dialog.py b/Lib/lib-tk/Dialog.py
index e529001..b52e5b4 100644
--- a/Lib/lib-tk/Dialog.py
+++ b/Lib/lib-tk/Dialog.py
@@ -15,11 +15,11 @@
         self.widgetName = '__dialog__'
         Widget._setup(self, master, cnf)
         self.num = self.tk.getint(
-                apply(self.tk.call,
-                      ('tk_dialog', self._w,
-                       cnf['title'], cnf['text'],
-                       cnf['bitmap'], cnf['default'])
-                      + cnf['strings']))
+                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
diff --git a/Lib/lib-tk/ScrolledText.py b/Lib/lib-tk/ScrolledText.py
index a14ae4d..367aa89 100644
--- a/Lib/lib-tk/ScrolledText.py
+++ b/Lib/lib-tk/ScrolledText.py
@@ -24,11 +24,11 @@
             if type(k) == ClassType or k == 'name':
                 fcnf[k] = cnf[k]
                 del cnf[k]
-        self.frame = apply(Frame, (master,), fcnf)
+        self.frame = Frame(master, **fcnf)
         self.vbar = Scrollbar(self.frame, name='vbar')
         self.vbar.pack(side=RIGHT, fill=Y)
         cnf['name'] = 'text'
-        apply(Text.__init__, (self, self.frame), cnf)
+        Text.__init__(self, self.frame, **cnf)
         self.pack(side=LEFT, fill=BOTH, expand=1)
         self['yscrollcommand'] = self.vbar.set
         self.vbar['command'] = self.yview
diff --git a/Lib/lib-tk/Tix.py b/Lib/lib-tk/Tix.py
index 98a06c2..99731cd 100755
--- a/Lib/lib-tk/Tix.py
+++ b/Lib/lib-tk/Tix.py
@@ -222,7 +222,7 @@
     See Tix documentation for complete details"""
 
     def config(self, cnf={}, **kw):
-        apply(self.tk.call, ('tixForm', self._w) + self._options(cnf, kw))
+        self.tk.call('tixForm', self._w, *self._options(cnf, kw))
 
     form = config
 
@@ -292,7 +292,7 @@
             static_options.append('options')
         else:
             static_options = ['options']
-            
+
         for k,v in cnf.items()[:]:
             if k in static_options:
                 extra = extra + ('-' + k, v)
@@ -304,7 +304,7 @@
         # If widgetName is None, this is a dummy creation call where the
         # corresponding Tk widget has already been created by Tix
         if widgetName:
-            apply(self.tk.call, (widgetName, self._w) + extra)
+            self.tk.call(widgetName, self._w, *extra)
 
         # Non-static options - to be done via a 'config' command
         if cnf:
@@ -474,8 +474,8 @@
         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 = apply(self.tk.call, ('tixDisplayStyle', itemtype) +
-                            self._options(cnf,kw) )
+        self.stylename = self.tk.call('tixDisplayStyle', itemtype,
+                            *self._options(cnf,kw) )
 
     def __str__(self):
         return self.stylename
@@ -499,8 +499,8 @@
     def config(self, cnf={}, **kw):
         return _lst2dict(
             self.tk.split(
-            apply(self.tk.call,
-                  (self.stylename, 'configure') + self._options(cnf,kw))))
+            self.tk.call(
+                  self.stylename, 'configure', *self._options(cnf,kw))))
 
     def __getitem__(self,key):
         return self.tk.call(self.stylename, 'cget', '-%s'%key)
@@ -532,8 +532,7 @@
     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"""
-        apply(self.tk.call,
-              (self._w, 'bind', widget._w) + self._options(cnf, kw))
+        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)
@@ -549,8 +548,7 @@
     def add(self, name, cnf={}, **kw):
         """Add a button with given name to box."""
 
-        btn = apply(self.tk.call,
-                    (self._w, 'add', name) + self._options(cnf, kw))
+        btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
         self.subwidget_list[name] = _dummyButton(self, name)
         return btn
 
@@ -589,7 +587,7 @@
             pass
 
     # align
-    
+
     def add_history(self, str):
         self.tk.call(self._w, 'addhistory', str)
 
@@ -862,14 +860,13 @@
                            ['columns', 'options'], cnf, kw)
 
     def add(self, entry, cnf={}, **kw):
-        return apply(self.tk.call,
-                     (self._w, 'add', entry) + self._options(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 apply(self.tk.call,
-                     (self._w, 'addchild', parent) + self._options(cnf, kw))
+        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)
@@ -909,16 +906,15 @@
         self.tk.call(self._w, 'dropsite', 'clear')
 
     def header_create(self, col, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'header', 'create', col) + self._options(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)))
-        apply(self.tk.call, (self._w, 'header', 'configure', col)
-              + self._options(cnf, kw))
+        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)
@@ -936,16 +932,16 @@
         self.tk.call(self._w, 'hide', 'entry', entry)
 
     def indicator_create(self, entry, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'indicator', 'create', entry) + self._options(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)))
-        apply(self.tk.call,
-              (self._w, 'indicator', 'configure', entry) + self._options(cnf, kw))
+        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)
@@ -996,12 +992,12 @@
             return _lst2dict(
                 self.tk.split(
                 self.tk.call(self._w, 'item', 'configure', entry, col)))
-        apply(self.tk.call, (self._w, 'item', 'configure', entry, col) +
-              self._options(cnf, kw))
+        self.tk.call(self._w, 'item', 'configure', entry, col,
+              *self._options(cnf, kw))
 
     def item_create(self, entry, col, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'item', 'create', entry, col) + self._options(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)
@@ -1016,8 +1012,7 @@
         self.tk.call(self._w, 'see', entry)
 
     def selection_clear(self, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'selection', 'clear') + self._options(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)
@@ -1029,10 +1024,10 @@
         return self.tk.call(self._w, 'show', 'entry', entry)
 
     def xview(self, *args):
-        apply(self.tk.call, (self._w, 'xview') + args)
+        self.tk.call(self._w, 'xview', *args)
 
     def yview(self, *args):
-        apply(self.tk.call, (self._w, 'yview') + args)
+        self.tk.call(self._w, 'yview', *args)
 
 class InputOnly(TixWidget):
     """InputOnly - Invisible widget. Unix only.
@@ -1093,8 +1088,7 @@
         self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist')
 
     def add(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', name) + self._options(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]
 
@@ -1135,8 +1129,7 @@
                                                       destroy_physically=0)
 
     def add(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', name) + self._options(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]
 
@@ -1180,12 +1173,10 @@
         self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
 
     def add_command(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', 'command', name) + self._options(cnf, kw))
+        self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw))
 
     def add_separator(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', 'separator', name) + self._options(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)
@@ -1212,8 +1203,7 @@
 
     # add delete forget panecget paneconfigure panes setsize
     def add(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', name) + self._options(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]
@@ -1234,8 +1224,7 @@
             return _lst2dict(
                 self.tk.split(
                 self.tk.call(self._w, 'paneconfigure', entry)))
-        apply(self.tk.call,
-              (self._w, 'paneconfigure', entry) + self._options(cnf, kw))
+        self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
 
     def panes(self):
         names = self.tk.call(self._w, 'panes')
@@ -1361,8 +1350,7 @@
         self.subwidget_list['label'] = _dummyLabel(self, 'label')
 
     def add(self, name, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'add', name) + self._options(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]
 
@@ -1458,8 +1446,7 @@
         self.tk.call(self._w, 'dropsite', 'clear')
 
     def insert(self, index, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'insert', index) + self._options(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')
@@ -1493,8 +1480,7 @@
         self.tk.call(self._w, 'see', index)
 
     def selection_clear(self, cnf={}, **kw):
-        apply(self.tk.call,
-              (self._w, 'selection', 'clear') + self._options(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)
@@ -1503,10 +1489,10 @@
         self.tk.call(self._w, 'selection', 'set', first, last)
 
     def xview(self, *args):
-        apply(self.tk.call, (self._w, 'xview') + args)
+        self.tk.call(self._w, 'xview', *args)
 
     def yview(self, *args):
-        apply(self.tk.call, (self._w, 'yview') + args)
+        self.tk.call(self._w, 'yview', *args)
 
 class Tree(TixWidget):
     """Tree - The tixTree widget can be used to display hierachical
@@ -1807,7 +1793,7 @@
     # def unset x y
     # def xview
     # def yview
-    
+
 class ScrolledGrid(TixWidget):
     '''Scrolled Grid widgets'''
 
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index 6db671a..8fa8e6e 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -4,10 +4,10 @@
 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. 
+LabelFrame and PanedWindow.
 
-Properties of the widgets are specified with keyword arguments.  
-Keyword arguments have the same name as the corresponding resource 
+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
@@ -444,7 +444,7 @@
             tmp = []
             def callit(func=func, args=args, self=self, tmp=tmp):
                 try:
-                    apply(func, args)
+                    func(*args)
                 finally:
                     try:
                         self.deletecommand(tmp[0])
@@ -459,7 +459,7 @@
 
         Return an identifier to cancel the scheduling with
         after_cancel."""
-        return apply(self.after, ('idle', func) + args)
+        return self.after('idle', func, *args)
     def after_cancel(self, id):
         """Cancel scheduling of function identified with ID.
 
@@ -1182,7 +1182,7 @@
             args = args + (column, row)
         if col2 is not None and row2 is not None:
             args = args + (col2, row2)
-        return self._getints(apply(self.tk.call, args)) or None
+        return self._getints(self.tk.call(*args)) or None
 
     bbox = grid_bbox
     def _grid_configure(self, command, index, cnf, kw):
@@ -1324,8 +1324,8 @@
         """Apply first function SUBST to arguments, than FUNC."""
         try:
             if self.subst:
-                args = apply(self.subst, args)
-            return apply(self.func, args)
+                args = self.subst(*args)
+            return self.func(*args)
         except SystemExit, msg:
             raise SystemExit, msg
         except:
@@ -1334,7 +1334,7 @@
 
 class Wm:
     """Provides functions for the communication with the window manager."""
-    
+
     def wm_aspect(self,
               minNumer=None, minDenom=None,
               maxNumer=None, maxDenom=None):
@@ -1346,29 +1346,29 @@
                      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 
+
+        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 
+
+        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 
+        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 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."""
@@ -1868,56 +1868,56 @@
     """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 
+            disabledforeground, font, foreground
             highlightbackground, highlightcolor,
-            highlightthickness, image, justify, 
+            highlightthickness, image, justify,
             padx, pady, relief, repeatdelay,
-            repeatinterval, takefocus, text, 
+            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 
+        """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, 
+        """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.
@@ -2028,10 +2028,9 @@
             args = args[:-1]
         else:
             cnf = {}
-        return getint(apply(
-            self.tk.call,
-            (self._w, 'create', itemType)
-            + args + self._options(cnf, kw)))
+        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)
@@ -2334,21 +2333,21 @@
     """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, 
+
+            activebackground, activeforeground, anchor,
+            background, bitmap, borderwidth, cursor,
             disabledforeground, font, foreground,
-            highlightbackground, highlightcolor, 
-            highlightthickness, image, justify, 
-            padx, pady, relief, takefocus, text, 
+            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)
 
@@ -2686,33 +2685,33 @@
         """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, 
+            relief, selectbackground,
             selectborderwidth, selectforeground,
-            setgrid, takefocus, 
+            setgrid, takefocus,
             xscrollcommand, yscrollcommand,
 
         WIDGET-SPECIFIC OPTIONS
-        
+
             autoseparators, height, maxundo,
-            spacing1, spacing2, spacing3, 
+            spacing1, spacing2, spacing3,
             state, tabs, undo, width, wrap,
-        
+
         """
         Widget.__init__(self, master, 'text', cnf, kw)
     def bbox(self, *args):
@@ -2748,13 +2747,13 @@
         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."""
@@ -2784,68 +2783,68 @@
         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 
+
+        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._getints(
             self.tk.call((self._w, 'edit') + args)) or ()
 
     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 
+        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 
+
+        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. 
-        
+        """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 
+        """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)
@@ -2862,9 +2861,9 @@
         return self._configure(('image', 'configure', index), cnf, kw)
     def image_create(self, index, cnf={}, **kw):
         """Create an embedded image at INDEX."""
-        return apply(self.tk.call,
-                 (self._w, "image", "create", index)
-                 + self._options(cnf, kw))
+        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")
@@ -3050,7 +3049,7 @@
     def __call__(self, *args):
         self.__var.set(self.__value)
         if self.__callback:
-            apply(self.__callback, (self.__value,)+args)
+            self.__callback(self.__value, *args)
 
 class OptionMenu(Menubutton):
     """OptionMenu which allows the user to select a value from a menu."""
@@ -3156,7 +3155,7 @@
 
         Valid resource names: data, format, file, gamma, height, palette,
         width."""
-        apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
+        Image.__init__(self, 'photo', name, cnf, master, **kw)
     def blank(self):
         """Display a transparent image."""
         self.tk.call(self.name, 'blank')
@@ -3215,7 +3214,7 @@
         """Create a bitmap with NAME.
 
         Valid resource names: background, data, file, foreground, maskdata, maskfile."""
-        apply(Image.__init__, (self, 'bitmap', name, cnf, master), kw)
+        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')
@@ -3225,154 +3224,154 @@
     """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, 
+            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, 
+
+            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 
+        """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 
+
+        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 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 
-        
+        """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 
-        
+        """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 
+        """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 
+        """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 
+
+        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 
+        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 
+        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 
+        """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 
+        """Sets or gets the currently selected element.
+
+        If a spinbutton element is specified, it will be
         displayed depressed
         """
         return self.selection("element", element)
@@ -3383,198 +3382,198 @@
     """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, 
+
+            borderwidth, cursor, font, foreground,
+            highlightbackground, highlightcolor,
+            highlightthickness, padx, pady, relief,
             takefocus, text
-            
+
         WIDGET-SPECIFIC OPTIONS
-        
-            background, class, colormap, container, 
-            height, labelanchor, labelwidget, 
+
+            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, 
+
+            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 
+        """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 
+
+        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 
+        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 ()          
-        
+            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. 
+        """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 
+        """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; 
-        
+        """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. 
-        
+        """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. 
-        
+        """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 
+        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 
+            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 
+            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. 
+            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 
+            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 
+            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 
+            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 
+            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 
+            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 
+            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 = {}
diff --git a/Lib/lib-tk/tkColorChooser.py b/Lib/lib-tk/tkColorChooser.py
index 77e856b..64858d1 100644
--- a/Lib/lib-tk/tkColorChooser.py
+++ b/Lib/lib-tk/tkColorChooser.py
@@ -63,7 +63,7 @@
         options = options.copy()
         options["initialcolor"] = color
 
-    return apply(Chooser, (), options).show()
+    return Chooser(**options).show()
 
 
 # --------------------------------------------------------------------
diff --git a/Lib/lib-tk/tkCommonDialog.py b/Lib/lib-tk/tkCommonDialog.py
index 5d460ce..6f2f1fa 100644
--- a/Lib/lib-tk/tkCommonDialog.py
+++ b/Lib/lib-tk/tkCommonDialog.py
@@ -49,7 +49,7 @@
 
         try:
 
-            s = apply(w.tk.call, (self.command,) + w._options(self.options))
+            s = w.tk.call(self.command, *w._options(self.options))
 
             s = self._fixresult(w, s)
 
diff --git a/Lib/lib-tk/tkFont.py b/Lib/lib-tk/tkFont.py
index 169c529..51cf9c3 100644
--- a/Lib/lib-tk/tkFont.py
+++ b/Lib/lib-tk/tkFont.py
@@ -73,7 +73,7 @@
         if not name:
             name = "font" + str(id(self))
         self.name = name
-        apply(root.tk.call, ("font", "create", name) + font)
+        root.tk.call("font", "create", name, *font)
         # backlinks!
         self._root  = root
         self._split = root.tk.splitlist
@@ -90,7 +90,7 @@
 
     def copy(self):
         "Return a distinct copy of the current font"
-        return apply(Font, (self._root,), self.actual())
+        return Font(self._root, **self.actual())
 
     def actual(self, option=None):
         "Return actual font attributes"
@@ -108,8 +108,8 @@
     def config(self, **options):
         "Modify font attributes"
         if options:
-            apply(self._call, ("font", "config", self.name) +
-                  self._set(options))
+            self._call("font", "config", self.name,
+                  *self._set(options))
         else:
             return self._mkdict(
                 self._split(self._call("font", "config", self.name))
diff --git a/Lib/lib-tk/tkMessageBox.py b/Lib/lib-tk/tkMessageBox.py
index a6de8c6..c2aa928 100644
--- a/Lib/lib-tk/tkMessageBox.py
+++ b/Lib/lib-tk/tkMessageBox.py
@@ -72,37 +72,37 @@
     if type:    options["type"] = type
     if title:   options["title"] = title
     if message: options["message"] = message
-    return apply(Message, (), options).show()
+    return Message(**options).show()
 
 def showinfo(title=None, message=None, **options):
     "Show an info message"
-    return apply(_show, (title, message, INFO, OK), options)
+    return _show(title, message, INFO, OK, **options)
 
 def showwarning(title=None, message=None, **options):
     "Show a warning message"
-    return apply(_show, (title, message, WARNING, OK), options)
+    return _show(title, message, WARNING, OK, **options)
 
 def showerror(title=None, message=None, **options):
     "Show an error message"
-    return apply(_show, (title, message, ERROR, OK), options)
+    return _show(title, message, ERROR, OK, **options)
 
 def askquestion(title=None, message=None, **options):
     "Ask a question"
-    return apply(_show, (title, message, QUESTION, YESNO), options)
+    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 = apply(_show, (title, message, QUESTION, OKCANCEL), options)
+    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 = apply(_show, (title, message, QUESTION, YESNO), options)
+    s = _show(title, message, QUESTION, YESNO, **options)
     return s == YES
 
 def askretrycancel(title=None, message=None, **options):
     "Ask if operation should be retried; return true if the answer is yes"
-    s = apply(_show, (title, message, WARNING, RETRYCANCEL), options)
+    s = _show(title, message, WARNING, RETRYCANCEL, **options)
     return s == RETRY
 
 
diff --git a/Lib/lib-tk/tkSimpleDialog.py b/Lib/lib-tk/tkSimpleDialog.py
index 3dac212..01709d8 100644
--- a/Lib/lib-tk/tkSimpleDialog.py
+++ b/Lib/lib-tk/tkSimpleDialog.py
@@ -249,7 +249,7 @@
 
     Return value is an integer
     '''
-    d = apply(_QueryInteger, (title, prompt), kw)
+    d = _QueryInteger(title, prompt, **kw)
     return d.result
 
 class _QueryFloat(_QueryDialog):
@@ -268,7 +268,7 @@
 
     Return value is a float
     '''
-    d = apply(_QueryFloat, (title, prompt), kw)
+    d = _QueryFloat(title, prompt, **kw)
     return d.result
 
 class _QueryString(_QueryDialog):
@@ -300,7 +300,7 @@
 
     Return value is a string
     '''
-    d = apply(_QueryString, (title, prompt), kw)
+    d = _QueryString(title, prompt, **kw)
     return d.result
 
 if __name__ == "__main__":
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 16e5735..e915ce9 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -354,11 +354,11 @@
 def up(): _getpen().up()
 def down(): _getpen().down()
 def width(width): _getpen().width(width)
-def color(*args): apply(_getpen().color, args)
+def color(*args): _getpen().color(*args)
 def write(arg, move=0): _getpen().write(arg, move)
 def fill(flag): _getpen().fill(flag)
 def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): apply(_getpen().goto, args)
+def goto(*args): _getpen().goto(*args)
 def heading(): return _getpen().heading()
 def setheading(angle): _getpen().setheading(angle)
 def position(): return _getpen().position()
diff --git a/Lib/plat-mac/Carbon/MediaDescr.py b/Lib/plat-mac/Carbon/MediaDescr.py
index 3c73820..acacfb1 100644
--- a/Lib/plat-mac/Carbon/MediaDescr.py
+++ b/Lib/plat-mac/Carbon/MediaDescr.py
@@ -4,94 +4,94 @@
 Error = 'MediaDescr.Error'
 
 class _MediaDescriptionCodec:
-	def __init__(self, trunc, size, names, fmt):
-		self.trunc = trunc
-		self.size = size
-		self.names = names
-		self.fmt = fmt
-		
-	def decode(self, data):
-		if self.trunc:
-			data = data[:self.size]
-		values = struct.unpack(self.fmt, data)
-		if len(values) != len(self.names):
-			raise Error, ('Format length does not match number of names', descr)
-		rv = {}
-		for i in range(len(values)):
-			name = self.names[i]
-			value = values[i]
-			if type(name) == type(()):
-				name, cod, dec = name
-				value = dec(value)
-			rv[name] = value
-		return rv
-		
-	def encode(dict):
-		list = [self.fmt]
-		for name in self.names:
-			if type(name) == type(()):
-				name, cod, dec = name
-			else:
-				cod = dec = None
-			value = dict[name]
-			if cod:
-				value = cod(value)
-			list.append(value)
-		rv = apply(struct.pack, tuple(list))
-		return rv
-		
+        def __init__(self, trunc, size, names, fmt):
+                self.trunc = trunc
+                self.size = size
+                self.names = names
+                self.fmt = fmt
+
+        def decode(self, data):
+                if self.trunc:
+                        data = data[:self.size]
+                values = struct.unpack(self.fmt, data)
+                if len(values) != len(self.names):
+                        raise Error, ('Format length does not match number of names', descr)
+                rv = {}
+                for i in range(len(values)):
+                        name = self.names[i]
+                        value = values[i]
+                        if type(name) == type(()):
+                                name, cod, dec = name
+                                value = dec(value)
+                        rv[name] = value
+                return rv
+
+        def encode(dict):
+                list = [self.fmt]
+                for name in self.names:
+                        if type(name) == type(()):
+                                name, cod, dec = name
+                        else:
+                                cod = dec = None
+                        value = dict[name]
+                        if cod:
+                                value = cod(value)
+                        list.append(value)
+                rv = struct.pack(*list)
+                return rv
+
 # Helper functions
 def _tofixed(float):
-	hi = int(float)
-	lo = int(float*0x10000) & 0xffff
-	return (hi<<16)|lo
-	
+        hi = int(float)
+        lo = int(float*0x10000) & 0xffff
+        return (hi<<16)|lo
+
 def _fromfixed(fixed):
-	hi = (fixed >> 16) & 0xffff
-	lo = (fixed & 0xffff)
-	return hi + (lo / float(0x10000))
-	
+        hi = (fixed >> 16) & 0xffff
+        lo = (fixed & 0xffff)
+        return hi + (lo / float(0x10000))
+
 def _tostr31(str):
-	return chr(len(str)) + str + '\0'*(31-len(str))
-	
+        return chr(len(str)) + str + '\0'*(31-len(str))
+
 def _fromstr31(str31):
-	return str31[1:1+ord(str31[0])]
+        return str31[1:1+ord(str31[0])]
 
 SampleDescription = _MediaDescriptionCodec(
-	1,	# May be longer, truncate
-	16,	# size
-	('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex'),	# Attributes
-	"l4slhh"	# Format
+        1,      # May be longer, truncate
+        16,     # size
+        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex'), # Attributes
+        "l4slhh"        # Format
 )
 
 SoundDescription = _MediaDescriptionCodec(
-	1,
-	36,
-	('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
-	'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
-	'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed)),
-	"l4slhhhh4shhhhl"	# Format
+        1,
+        36,
+        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
+        'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
+        'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed)),
+        "l4slhhhh4shhhhl"       # Format
 )
 
 SoundDescriptionV1 = _MediaDescriptionCodec(
-	1,
-	52,
-	('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
-	'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
-	'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed), 'samplesPerPacket',
-	'bytesPerPacket', 'bytesPerFrame', 'bytesPerSample'),
-	"l4slhhhh4shhhhlllll"	# Format
+        1,
+        52,
+        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
+        'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
+        'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed), 'samplesPerPacket',
+        'bytesPerPacket', 'bytesPerFrame', 'bytesPerSample'),
+        "l4slhhhh4shhhhlllll"   # Format
 )
 
 ImageDescription = _MediaDescriptionCodec(
-	1,	# May be longer, truncate
-	86,	# size
-	('idSize', 'cType', 'resvd1', 'resvd2', 'dataRefIndex', 'version',
-	 'revisionLevel', 'vendor', 'temporalQuality', 'spatialQuality',
-	 'width', 'height', ('hRes', _tofixed, _fromfixed), ('vRes', _tofixed, _fromfixed), 
-	'dataSize', 'frameCount', ('name', _tostr31, _fromstr31),
-	 'depth', 'clutID'),
-	'l4slhhhh4sllhhlllh32shh',
+        1,      # May be longer, truncate
+        86,     # size
+        ('idSize', 'cType', 'resvd1', 'resvd2', 'dataRefIndex', 'version',
+         'revisionLevel', 'vendor', 'temporalQuality', 'spatialQuality',
+         'width', 'height', ('hRes', _tofixed, _fromfixed), ('vRes', _tofixed, _fromfixed),
+        'dataSize', 'frameCount', ('name', _tostr31, _fromstr31),
+         'depth', 'clutID'),
+        'l4slhhhh4sllhhlllh32shh',
 )
 
 # XXXX Others, like TextDescription and such, remain to be done.
diff --git a/Lib/plat-mac/EasyDialogs.py b/Lib/plat-mac/EasyDialogs.py
index 27219a2..4a92373 100644
--- a/Lib/plat-mac/EasyDialogs.py
+++ b/Lib/plat-mac/EasyDialogs.py
@@ -5,13 +5,13 @@
 AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
 AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
 GetArgv(optionlist, commandlist) -- fill a sys.argv-like list using a dialog
-AskFileForOpen(...) -- Ask the user for an existing file 
+AskFileForOpen(...) -- Ask the user for an existing file
 AskFileForSave(...) -- Ask the user for an output file
 AskFolder(...) -- Ask the user to select a folder
 bar = Progress(label, maxvalue) -- Display a progress bar
 bar.set(value) -- Set value
 bar.inc( *amount ) -- increment value by amount (default=1)
-bar.label( *newlabel ) -- get or set text label. 
+bar.label( *newlabel ) -- get or set text label.
 
 More documentation in each function.
 This module uses DLOG resources 260 and on.
@@ -31,309 +31,309 @@
 import Nav
 import MacOS
 import string
-from Carbon.ControlAccessor import *	# Also import Controls constants
+from Carbon.ControlAccessor import *    # Also import Controls constants
 import Carbon.File
 import macresource
 import os
 import sys
 
 __all__ = ['Message', 'AskString', 'AskPassword', 'AskYesNoCancel',
-	'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
-	'Progress']
-	
+        'GetArgv', 'AskFileForOpen', 'AskFileForSave', 'AskFolder',
+        'Progress']
+
 _initialized = 0
 
 def _initialize():
-	global _initialized
-	if _initialized: return
-	macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
-	
+        global _initialized
+        if _initialized: return
+        macresource.need("DLOG", 260, "dialogs.rsrc", __name__)
+
 def _interact():
-	"""Make sure the application is in the foreground"""
-	AE.AEInteractWithUser(50000000)
+        """Make sure the application is in the foreground"""
+        AE.AEInteractWithUser(50000000)
 
 def cr2lf(text):
-	if '\r' in text:
-		text = string.join(string.split(text, '\r'), '\n')
-	return text
+        if '\r' in text:
+                text = string.join(string.split(text, '\r'), '\n')
+        return text
 
 def lf2cr(text):
-	if '\n' in text:
-		text = string.join(string.split(text, '\n'), '\r')
-	if len(text) > 253:
-		text = text[:253] + '\311'
-	return text
+        if '\n' in text:
+                text = string.join(string.split(text, '\n'), '\r')
+        if len(text) > 253:
+                text = text[:253] + '\311'
+        return text
 
 def Message(msg, id=260, ok=None):
-	"""Display a MESSAGE string.
-	
-	Return when the user clicks the OK button or presses Return.
-	
-	The MESSAGE string can be at most 255 characters long.
-	"""
-	_initialize()
-	_interact()
-	d = GetNewDialog(id, -1)
-	if not d:
-		print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
-		return
-	h = d.GetDialogItemAsControl(2)
-	SetDialogItemText(h, lf2cr(msg))
-	if ok != None:
-		h = d.GetDialogItemAsControl(1)
-		h.SetControlTitle(ok)
-	d.SetDialogDefaultItem(1)
-	d.AutoSizeDialog()
-	d.GetDialogWindow().ShowWindow()
-	while 1:
-		n = ModalDialog(None)
-		if n == 1:
-			return
+        """Display a MESSAGE string.
+
+        Return when the user clicks the OK button or presses Return.
+
+        The MESSAGE string can be at most 255 characters long.
+        """
+        _initialize()
+        _interact()
+        d = GetNewDialog(id, -1)
+        if not d:
+                print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
+                return
+        h = d.GetDialogItemAsControl(2)
+        SetDialogItemText(h, lf2cr(msg))
+        if ok != None:
+                h = d.GetDialogItemAsControl(1)
+                h.SetControlTitle(ok)
+        d.SetDialogDefaultItem(1)
+        d.AutoSizeDialog()
+        d.GetDialogWindow().ShowWindow()
+        while 1:
+                n = ModalDialog(None)
+                if n == 1:
+                        return
 
 
 def AskString(prompt, default = "", id=261, ok=None, cancel=None):
-	"""Display a PROMPT string and a text entry field with a DEFAULT string.
-	
-	Return the contents of the text entry field when the user clicks the
-	OK button or presses Return.
-	Return None when the user clicks the Cancel button.
-	
-	If omitted, DEFAULT is empty.
-	
-	The PROMPT and DEFAULT strings, as well as the return value,
-	can be at most 255 characters long.
-	"""
-	
-	_initialize()
-	_interact()
-	d = GetNewDialog(id, -1)
-	if not d:
-		print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
-		return
-	h = d.GetDialogItemAsControl(3)
-	SetDialogItemText(h, lf2cr(prompt))
-	h = d.GetDialogItemAsControl(4)
-	SetDialogItemText(h, lf2cr(default))
-	d.SelectDialogItemText(4, 0, 999)
-#	d.SetDialogItem(4, 0, 255)
-	if ok != None:
-		h = d.GetDialogItemAsControl(1)
-		h.SetControlTitle(ok)
-	if cancel != None:
-		h = d.GetDialogItemAsControl(2)
-		h.SetControlTitle(cancel)
-	d.SetDialogDefaultItem(1)
-	d.SetDialogCancelItem(2)
-	d.AutoSizeDialog()
-	d.GetDialogWindow().ShowWindow()
-	while 1:
-		n = ModalDialog(None)
-		if n == 1:
-			h = d.GetDialogItemAsControl(4)
-			return cr2lf(GetDialogItemText(h))
-		if n == 2: return None
+        """Display a PROMPT string and a text entry field with a DEFAULT string.
 
-def AskPassword(prompt,	 default='', id=264, ok=None, cancel=None):	
-	"""Display a PROMPT string and a text entry field with a DEFAULT string.
-	The string is displayed as bullets only.
-	
-	Return the contents of the text entry field when the user clicks the
-	OK button or presses Return.
-	Return None when the user clicks the Cancel button.
-	
-	If omitted, DEFAULT is empty.
-	
-	The PROMPT and DEFAULT strings, as well as the return value,
-	can be at most 255 characters long.
-	"""
-	_initialize()
-	_interact()
-	d = GetNewDialog(id, -1)
-	if not d:
-		print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
-		return
-	h = d.GetDialogItemAsControl(3)
-	SetDialogItemText(h, lf2cr(prompt))	
-	pwd = d.GetDialogItemAsControl(4)
-	bullets = '\245'*len(default)
-##	SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
-	SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
-	d.SelectDialogItemText(4, 0, 999)
-	Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
-	if ok != None:
-		h = d.GetDialogItemAsControl(1)
-		h.SetControlTitle(ok)
-	if cancel != None:
-		h = d.GetDialogItemAsControl(2)
-		h.SetControlTitle(cancel)
-	d.SetDialogDefaultItem(Dialogs.ok)
-	d.SetDialogCancelItem(Dialogs.cancel)
-	d.AutoSizeDialog()
-	d.GetDialogWindow().ShowWindow()
-	while 1:
-		n = ModalDialog(None)
-		if n == 1:
-			h = d.GetDialogItemAsControl(4)
-			return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
-		if n == 2: return None
+        Return the contents of the text entry field when the user clicks the
+        OK button or presses Return.
+        Return None when the user clicks the Cancel button.
+
+        If omitted, DEFAULT is empty.
+
+        The PROMPT and DEFAULT strings, as well as the return value,
+        can be at most 255 characters long.
+        """
+
+        _initialize()
+        _interact()
+        d = GetNewDialog(id, -1)
+        if not d:
+                print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
+                return
+        h = d.GetDialogItemAsControl(3)
+        SetDialogItemText(h, lf2cr(prompt))
+        h = d.GetDialogItemAsControl(4)
+        SetDialogItemText(h, lf2cr(default))
+        d.SelectDialogItemText(4, 0, 999)
+#       d.SetDialogItem(4, 0, 255)
+        if ok != None:
+                h = d.GetDialogItemAsControl(1)
+                h.SetControlTitle(ok)
+        if cancel != None:
+                h = d.GetDialogItemAsControl(2)
+                h.SetControlTitle(cancel)
+        d.SetDialogDefaultItem(1)
+        d.SetDialogCancelItem(2)
+        d.AutoSizeDialog()
+        d.GetDialogWindow().ShowWindow()
+        while 1:
+                n = ModalDialog(None)
+                if n == 1:
+                        h = d.GetDialogItemAsControl(4)
+                        return cr2lf(GetDialogItemText(h))
+                if n == 2: return None
+
+def AskPassword(prompt,  default='', id=264, ok=None, cancel=None):
+        """Display a PROMPT string and a text entry field with a DEFAULT string.
+        The string is displayed as bullets only.
+
+        Return the contents of the text entry field when the user clicks the
+        OK button or presses Return.
+        Return None when the user clicks the Cancel button.
+
+        If omitted, DEFAULT is empty.
+
+        The PROMPT and DEFAULT strings, as well as the return value,
+        can be at most 255 characters long.
+        """
+        _initialize()
+        _interact()
+        d = GetNewDialog(id, -1)
+        if not d:
+                print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
+                return
+        h = d.GetDialogItemAsControl(3)
+        SetDialogItemText(h, lf2cr(prompt))
+        pwd = d.GetDialogItemAsControl(4)
+        bullets = '\245'*len(default)
+##      SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
+        SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
+        d.SelectDialogItemText(4, 0, 999)
+        Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
+        if ok != None:
+                h = d.GetDialogItemAsControl(1)
+                h.SetControlTitle(ok)
+        if cancel != None:
+                h = d.GetDialogItemAsControl(2)
+                h.SetControlTitle(cancel)
+        d.SetDialogDefaultItem(Dialogs.ok)
+        d.SetDialogCancelItem(Dialogs.cancel)
+        d.AutoSizeDialog()
+        d.GetDialogWindow().ShowWindow()
+        while 1:
+                n = ModalDialog(None)
+                if n == 1:
+                        h = d.GetDialogItemAsControl(4)
+                        return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
+                if n == 2: return None
 
 def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
-	"""Display a QUESTION string which can be answered with Yes or No.
-	
-	Return 1 when the user clicks the Yes button.
-	Return 0 when the user clicks the No button.
-	Return -1 when the user clicks the Cancel button.
-	
-	When the user presses Return, the DEFAULT value is returned.
-	If omitted, this is 0 (No).
-	
-	The QUESTION string can be at most 255 characters.
-	"""
-	
-	_initialize()
-	_interact()
-	d = GetNewDialog(id, -1)
-	if not d:
-		print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
-		return
-	# Button assignments:
-	# 1 = default (invisible)
-	# 2 = Yes
-	# 3 = No
-	# 4 = Cancel
-	# The question string is item 5
-	h = d.GetDialogItemAsControl(5)
-	SetDialogItemText(h, lf2cr(question))
-	if yes != None:
-		if yes == '':
-			d.HideDialogItem(2)
-		else:
-			h = d.GetDialogItemAsControl(2)
-			h.SetControlTitle(yes)
-	if no != None:
-		if no == '':
-			d.HideDialogItem(3)
-		else:
-			h = d.GetDialogItemAsControl(3)
-			h.SetControlTitle(no)
-	if cancel != None:
-		if cancel == '':
-			d.HideDialogItem(4)
-		else:
-			h = d.GetDialogItemAsControl(4)
-			h.SetControlTitle(cancel)
-	d.SetDialogCancelItem(4)
-	if default == 1:
-		d.SetDialogDefaultItem(2)
-	elif default == 0:
-		d.SetDialogDefaultItem(3)
-	elif default == -1:
-		d.SetDialogDefaultItem(4)
-	d.AutoSizeDialog()
-	d.GetDialogWindow().ShowWindow()
-	while 1:
-		n = ModalDialog(None)
-		if n == 1: return default
-		if n == 2: return 1
-		if n == 3: return 0
-		if n == 4: return -1
+        """Display a QUESTION string which can be answered with Yes or No.
+
+        Return 1 when the user clicks the Yes button.
+        Return 0 when the user clicks the No button.
+        Return -1 when the user clicks the Cancel button.
+
+        When the user presses Return, the DEFAULT value is returned.
+        If omitted, this is 0 (No).
+
+        The QUESTION string can be at most 255 characters.
+        """
+
+        _initialize()
+        _interact()
+        d = GetNewDialog(id, -1)
+        if not d:
+                print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
+                return
+        # Button assignments:
+        # 1 = default (invisible)
+        # 2 = Yes
+        # 3 = No
+        # 4 = Cancel
+        # The question string is item 5
+        h = d.GetDialogItemAsControl(5)
+        SetDialogItemText(h, lf2cr(question))
+        if yes != None:
+                if yes == '':
+                        d.HideDialogItem(2)
+                else:
+                        h = d.GetDialogItemAsControl(2)
+                        h.SetControlTitle(yes)
+        if no != None:
+                if no == '':
+                        d.HideDialogItem(3)
+                else:
+                        h = d.GetDialogItemAsControl(3)
+                        h.SetControlTitle(no)
+        if cancel != None:
+                if cancel == '':
+                        d.HideDialogItem(4)
+                else:
+                        h = d.GetDialogItemAsControl(4)
+                        h.SetControlTitle(cancel)
+        d.SetDialogCancelItem(4)
+        if default == 1:
+                d.SetDialogDefaultItem(2)
+        elif default == 0:
+                d.SetDialogDefaultItem(3)
+        elif default == -1:
+                d.SetDialogDefaultItem(4)
+        d.AutoSizeDialog()
+        d.GetDialogWindow().ShowWindow()
+        while 1:
+                n = ModalDialog(None)
+                if n == 1: return default
+                if n == 2: return 1
+                if n == 3: return 0
+                if n == 4: return -1
 
 
-		
+
 
 screenbounds = Qd.GetQDGlobalsScreenBits().bounds
 screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
-	screenbounds[2]-4, screenbounds[3]-4
+        screenbounds[2]-4, screenbounds[3]-4
 
-kControlProgressBarIndeterminateTag = 'inde'	# from Controls.py
+kControlProgressBarIndeterminateTag = 'inde'    # from Controls.py
 
 
 class ProgressBar:
-	def __init__(self, title="Working...", maxval=0, label="", id=263):
-		self.w = None
-		self.d = None
-		_initialize()
-		self.d = GetNewDialog(id, -1)
-		self.w = self.d.GetDialogWindow()
-		self.label(label)
-		self.title(title)
-		self.set(0, maxval)
-		self.d.AutoSizeDialog()
-		self.w.ShowWindow()
-		self.d.DrawDialog()
+        def __init__(self, title="Working...", maxval=0, label="", id=263):
+                self.w = None
+                self.d = None
+                _initialize()
+                self.d = GetNewDialog(id, -1)
+                self.w = self.d.GetDialogWindow()
+                self.label(label)
+                self.title(title)
+                self.set(0, maxval)
+                self.d.AutoSizeDialog()
+                self.w.ShowWindow()
+                self.d.DrawDialog()
 
-	def __del__( self ):
-		if self.w:
-			self.w.BringToFront()
-			self.w.HideWindow()
-		del self.w
-		del self.d
-		
-	def title(self, newstr=""):
-		"""title(text) - Set title of progress window"""
-		self.w.BringToFront()
-		self.w.SetWTitle(newstr)
-		
-	def label( self, *newstr ):
-		"""label(text) - Set text in progress box"""
-		self.w.BringToFront()
-		if newstr:
-			self._label = lf2cr(newstr[0])
-		text_h = self.d.GetDialogItemAsControl(2)
-		SetDialogItemText(text_h, self._label)
+        def __del__( self ):
+                if self.w:
+                        self.w.BringToFront()
+                        self.w.HideWindow()
+                del self.w
+                del self.d
 
-	def _update(self, value):
-		maxval = self.maxval
-		if maxval == 0:		# an indeterminate bar
-			Ctl.IdleControls(self.w)	# spin the barber pole
-		else:				# a determinate bar
-			if maxval > 32767:
-				value = int(value/(maxval/32767.0))
-				maxval = 32767
-			maxval = int(maxval)
-			value = int(value)
-			progbar = self.d.GetDialogItemAsControl(3)
-			progbar.SetControlMaximum(maxval)
-			progbar.SetControlValue(value)	# set the bar length
+        def title(self, newstr=""):
+                """title(text) - Set title of progress window"""
+                self.w.BringToFront()
+                self.w.SetWTitle(newstr)
 
-		# Test for cancel button
-		ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1  )
-		if ready :
-			what,msg,when,where,mod = ev
-			part = Win.FindWindow(where)[0]
-			if Dlg.IsDialogEvent(ev):
-				ds = Dlg.DialogSelect(ev)
-				if ds[0] and ds[1] == self.d and ds[-1] == 1:
-					self.w.HideWindow()
-					self.w = None
-					self.d = None
-					raise KeyboardInterrupt, ev
-			else:
-				if part == 4:	# inDrag 
-					self.w.DragWindow(where, screenbounds)
-				else:
-					MacOS.HandleEvent(ev) 
-			
-			
-	def set(self, value, max=None):
-		"""set(value) - Set progress bar position"""
-		if max != None:
-			self.maxval = max
-			bar = self.d.GetDialogItemAsControl(3)
-			if max <= 0:	# indeterminate bar
-				bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
-			else:			# determinate bar
-				bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
-		if value < 0:
-			value = 0
-		elif value > self.maxval:
-			value = self.maxval
-		self.curval = value
-		self._update(value)
+        def label( self, *newstr ):
+                """label(text) - Set text in progress box"""
+                self.w.BringToFront()
+                if newstr:
+                        self._label = lf2cr(newstr[0])
+                text_h = self.d.GetDialogItemAsControl(2)
+                SetDialogItemText(text_h, self._label)
 
-	def inc(self, n=1):
-		"""inc(amt) - Increment progress bar position"""
-		self.set(self.curval + n)
+        def _update(self, value):
+                maxval = self.maxval
+                if maxval == 0:         # an indeterminate bar
+                        Ctl.IdleControls(self.w)        # spin the barber pole
+                else:                           # a determinate bar
+                        if maxval > 32767:
+                                value = int(value/(maxval/32767.0))
+                                maxval = 32767
+                        maxval = int(maxval)
+                        value = int(value)
+                        progbar = self.d.GetDialogItemAsControl(3)
+                        progbar.SetControlMaximum(maxval)
+                        progbar.SetControlValue(value)  # set the bar length
+
+                # Test for cancel button
+                ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1  )
+                if ready :
+                        what,msg,when,where,mod = ev
+                        part = Win.FindWindow(where)[0]
+                        if Dlg.IsDialogEvent(ev):
+                                ds = Dlg.DialogSelect(ev)
+                                if ds[0] and ds[1] == self.d and ds[-1] == 1:
+                                        self.w.HideWindow()
+                                        self.w = None
+                                        self.d = None
+                                        raise KeyboardInterrupt, ev
+                        else:
+                                if part == 4:   # inDrag
+                                        self.w.DragWindow(where, screenbounds)
+                                else:
+                                        MacOS.HandleEvent(ev)
+
+
+        def set(self, value, max=None):
+                """set(value) - Set progress bar position"""
+                if max != None:
+                        self.maxval = max
+                        bar = self.d.GetDialogItemAsControl(3)
+                        if max <= 0:    # indeterminate bar
+                                bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x01')
+                        else:                   # determinate bar
+                                bar.SetControlData(0,kControlProgressBarIndeterminateTag,'\x00')
+                if value < 0:
+                        value = 0
+                elif value > self.maxval:
+                        value = self.maxval
+                self.curval = value
+                self._update(value)
+
+        def inc(self, n=1):
+                """inc(amt) - Increment progress bar position"""
+                self.set(self.curval + n)
 
 ARGV_ID=265
 ARGV_ITEM_OK=1
@@ -352,488 +352,488 @@
 ARGV_CMDLINE_DATA=14
 
 ##def _myModalDialog(d):
-##	while 1:
-##		ready, ev = Evt.WaitNextEvent(0xffff, -1)
-##		print 'DBG: WNE', ready, ev
-##		if ready : 
-##			what,msg,when,where,mod = ev
-##			part, window = Win.FindWindow(where)
-##			if Dlg.IsDialogEvent(ev):
-##				didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
-##				print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
-##				if didit and dlgdone == d:
-##					return itemdone
-##			elif window == d.GetDialogWindow():
-##				d.GetDialogWindow().SelectWindow()
-##				if part == 4:	# inDrag 
-##						d.DragWindow(where, screenbounds)
-##				else:
-##					MacOS.HandleEvent(ev) 
-##			else:
-##				MacOS.HandleEvent(ev) 
+##      while 1:
+##              ready, ev = Evt.WaitNextEvent(0xffff, -1)
+##              print 'DBG: WNE', ready, ev
+##              if ready :
+##                      what,msg,when,where,mod = ev
+##                      part, window = Win.FindWindow(where)
+##                      if Dlg.IsDialogEvent(ev):
+##                              didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
+##                              print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
+##                              if didit and dlgdone == d:
+##                                      return itemdone
+##                      elif window == d.GetDialogWindow():
+##                              d.GetDialogWindow().SelectWindow()
+##                              if part == 4:   # inDrag
+##                                              d.DragWindow(where, screenbounds)
+##                              else:
+##                                      MacOS.HandleEvent(ev)
+##                      else:
+##                              MacOS.HandleEvent(ev)
 ##
 def _setmenu(control, items):
-		mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
-				Controls.kControlPopupButtonMenuHandleTag)
-		menu = Menu.as_Menu(mhandle)
-		for item in items:
-			if type(item) == type(()):
-				label = item[0]
-			else:
-				label = item
-			if label[-1] == '=' or label[-1] == ':':
-				label = label[:-1]
-			menu.AppendMenu(label)
-##		mhandle, mid = menu.getpopupinfo()
-##		control.SetControlData_Handle(Controls.kControlMenuPart,
-##				Controls.kControlPopupButtonMenuHandleTag, mhandle)
-		control.SetControlMinimum(1)
-		control.SetControlMaximum(len(items)+1)
-		
+                mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
+                                Controls.kControlPopupButtonMenuHandleTag)
+                menu = Menu.as_Menu(mhandle)
+                for item in items:
+                        if type(item) == type(()):
+                                label = item[0]
+                        else:
+                                label = item
+                        if label[-1] == '=' or label[-1] == ':':
+                                label = label[:-1]
+                        menu.AppendMenu(label)
+##              mhandle, mid = menu.getpopupinfo()
+##              control.SetControlData_Handle(Controls.kControlMenuPart,
+##                              Controls.kControlPopupButtonMenuHandleTag, mhandle)
+                control.SetControlMinimum(1)
+                control.SetControlMaximum(len(items)+1)
+
 def _selectoption(d, optionlist, idx):
-	if idx < 0 or idx >= len(optionlist):
-		MacOS.SysBeep()
-		return
-	option = optionlist[idx]
-	if type(option) == type(()):
-		if len(option) == 4:
-			help = option[2]
-		elif len(option) > 1:
-			help = option[-1]
-		else:
-			help = ''
-	else:
-		help = ''
-	h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
-	if help and len(help) > 250:
-		help = help[:250] + '...'
-	Dlg.SetDialogItemText(h, help)
-	hasvalue = 0
-	if type(option) == type(()):
-		label = option[0]
-	else:
-		label = option
-	if label[-1] == '=' or label[-1] == ':':
-		hasvalue = 1
-	h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
-	Dlg.SetDialogItemText(h, '')
-	if hasvalue:
-		d.ShowDialogItem(ARGV_OPTION_VALUE)
-		d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
-	else:
-		d.HideDialogItem(ARGV_OPTION_VALUE)
+        if idx < 0 or idx >= len(optionlist):
+                MacOS.SysBeep()
+                return
+        option = optionlist[idx]
+        if type(option) == type(()):
+                if len(option) == 4:
+                        help = option[2]
+                elif len(option) > 1:
+                        help = option[-1]
+                else:
+                        help = ''
+        else:
+                help = ''
+        h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
+        if help and len(help) > 250:
+                help = help[:250] + '...'
+        Dlg.SetDialogItemText(h, help)
+        hasvalue = 0
+        if type(option) == type(()):
+                label = option[0]
+        else:
+                label = option
+        if label[-1] == '=' or label[-1] == ':':
+                hasvalue = 1
+        h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
+        Dlg.SetDialogItemText(h, '')
+        if hasvalue:
+                d.ShowDialogItem(ARGV_OPTION_VALUE)
+                d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
+        else:
+                d.HideDialogItem(ARGV_OPTION_VALUE)
 
 
 def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
-	_initialize()
-	_interact()
-	d = GetNewDialog(id, -1)
-	if not d:
-		print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
-		return
-#	h = d.GetDialogItemAsControl(3)
-#	SetDialogItemText(h, lf2cr(prompt))
-#	h = d.GetDialogItemAsControl(4)
-#	SetDialogItemText(h, lf2cr(default))
-#	d.SelectDialogItemText(4, 0, 999)
-#	d.SetDialogItem(4, 0, 255)
-	if optionlist:
-		_setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
-		_selectoption(d, optionlist, 0)
-	else:
-		d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
-	if commandlist:
-		_setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
-		if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
-			help = commandlist[0][-1]
-			h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
-			Dlg.SetDialogItemText(h, help)
-	else:
-		d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
-	if not addoldfile:
-		d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
-	if not addnewfile:
-		d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
-	if not addfolder:
-		d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
-	d.SetDialogDefaultItem(ARGV_ITEM_OK)
-	d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
-	d.GetDialogWindow().ShowWindow()
-	d.DrawDialog()
-	if hasattr(MacOS, 'SchedParams'):
-		appsw = MacOS.SchedParams(1, 0)
-	try:
-		while 1:
-			stringstoadd = []
-			n = ModalDialog(None)
-			if n == ARGV_ITEM_OK:
-				break
-			elif n == ARGV_ITEM_CANCEL:
-				raise SystemExit
-			elif n == ARGV_OPTION_GROUP:
-				idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
-				_selectoption(d, optionlist, idx)
-			elif n == ARGV_OPTION_VALUE:
-				pass
-			elif n == ARGV_OPTION_ADD:
-				idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
-				if 0 <= idx < len(optionlist):
-					option = optionlist[idx]
-					if type(option) == type(()):
-						option = option[0]
-					if option[-1] == '=' or option[-1] == ':':
-						option = option[:-1]
-						h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
-						value = Dlg.GetDialogItemText(h)
-					else:
-						value = ''
-					if len(option) == 1:
-						stringtoadd = '-' + option
-					else:
-						stringtoadd = '--' + option
-					stringstoadd = [stringtoadd]
-					if value:
-						stringstoadd.append(value)
-				else:
-					MacOS.SysBeep()
-			elif n == ARGV_COMMAND_GROUP:
-				idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
-				if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
-						len(commandlist[idx]) > 1:
-					help = commandlist[idx][-1]
-					h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
-					Dlg.SetDialogItemText(h, help)
-			elif n == ARGV_COMMAND_ADD:
-				idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
-				if 0 <= idx < len(commandlist):
-					command = commandlist[idx]
-					if type(command) == type(()):
-						command = command[0]
-					stringstoadd = [command]
-				else:
-					MacOS.SysBeep()
-			elif n == ARGV_ADD_OLDFILE:
-				pathname = AskFileForOpen()
-				if pathname:
-					stringstoadd = [pathname]
-			elif n == ARGV_ADD_NEWFILE:
-				pathname = AskFileForSave()
-				if pathname:
-					stringstoadd = [pathname]
-			elif n == ARGV_ADD_FOLDER:
-				pathname = AskFolder()
-				if pathname:
-					stringstoadd = [pathname]
-			elif n == ARGV_CMDLINE_DATA:
-				pass # Nothing to do
-			else:
-				raise RuntimeError, "Unknown dialog item %d"%n
-			
-			for stringtoadd in stringstoadd:
-				if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
-					stringtoadd = `stringtoadd`
-				h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
-				oldstr = GetDialogItemText(h)
-				if oldstr and oldstr[-1] != ' ':
-					oldstr = oldstr + ' '
-				oldstr = oldstr + stringtoadd
-				if oldstr[-1] != ' ':
-					oldstr = oldstr + ' '
-				SetDialogItemText(h, oldstr)
-				d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
-		h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
-		oldstr = GetDialogItemText(h)
-		tmplist = string.split(oldstr)
-		newlist = []
-		while tmplist:
-			item = tmplist[0]
-			del tmplist[0]
-			if item[0] == '"':
-				while item[-1] != '"':
-					if not tmplist:
-						raise RuntimeError, "Unterminated quoted argument"
-					item = item + ' ' + tmplist[0]
-					del tmplist[0]
-				item = item[1:-1]
-			if item[0] == "'":
-				while item[-1] != "'":
-					if not tmplist:
-						raise RuntimeError, "Unterminated quoted argument"
-					item = item + ' ' + tmplist[0]
-					del tmplist[0]
-				item = item[1:-1]
-			newlist.append(item)
-		return newlist
-	finally:
-		if hasattr(MacOS, 'SchedParams'):
-			apply(MacOS.SchedParams, appsw)
-		del d
+        _initialize()
+        _interact()
+        d = GetNewDialog(id, -1)
+        if not d:
+                print "EasyDialogs: Can't get DLOG resource with id =", id, " (missing resource file?)"
+                return
+#       h = d.GetDialogItemAsControl(3)
+#       SetDialogItemText(h, lf2cr(prompt))
+#       h = d.GetDialogItemAsControl(4)
+#       SetDialogItemText(h, lf2cr(default))
+#       d.SelectDialogItemText(4, 0, 999)
+#       d.SetDialogItem(4, 0, 255)
+        if optionlist:
+                _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
+                _selectoption(d, optionlist, 0)
+        else:
+                d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
+        if commandlist:
+                _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
+                if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
+                        help = commandlist[0][-1]
+                        h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
+                        Dlg.SetDialogItemText(h, help)
+        else:
+                d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
+        if not addoldfile:
+                d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
+        if not addnewfile:
+                d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
+        if not addfolder:
+                d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
+        d.SetDialogDefaultItem(ARGV_ITEM_OK)
+        d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
+        d.GetDialogWindow().ShowWindow()
+        d.DrawDialog()
+        if hasattr(MacOS, 'SchedParams'):
+                appsw = MacOS.SchedParams(1, 0)
+        try:
+                while 1:
+                        stringstoadd = []
+                        n = ModalDialog(None)
+                        if n == ARGV_ITEM_OK:
+                                break
+                        elif n == ARGV_ITEM_CANCEL:
+                                raise SystemExit
+                        elif n == ARGV_OPTION_GROUP:
+                                idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
+                                _selectoption(d, optionlist, idx)
+                        elif n == ARGV_OPTION_VALUE:
+                                pass
+                        elif n == ARGV_OPTION_ADD:
+                                idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
+                                if 0 <= idx < len(optionlist):
+                                        option = optionlist[idx]
+                                        if type(option) == type(()):
+                                                option = option[0]
+                                        if option[-1] == '=' or option[-1] == ':':
+                                                option = option[:-1]
+                                                h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
+                                                value = Dlg.GetDialogItemText(h)
+                                        else:
+                                                value = ''
+                                        if len(option) == 1:
+                                                stringtoadd = '-' + option
+                                        else:
+                                                stringtoadd = '--' + option
+                                        stringstoadd = [stringtoadd]
+                                        if value:
+                                                stringstoadd.append(value)
+                                else:
+                                        MacOS.SysBeep()
+                        elif n == ARGV_COMMAND_GROUP:
+                                idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
+                                if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
+                                                len(commandlist[idx]) > 1:
+                                        help = commandlist[idx][-1]
+                                        h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
+                                        Dlg.SetDialogItemText(h, help)
+                        elif n == ARGV_COMMAND_ADD:
+                                idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
+                                if 0 <= idx < len(commandlist):
+                                        command = commandlist[idx]
+                                        if type(command) == type(()):
+                                                command = command[0]
+                                        stringstoadd = [command]
+                                else:
+                                        MacOS.SysBeep()
+                        elif n == ARGV_ADD_OLDFILE:
+                                pathname = AskFileForOpen()
+                                if pathname:
+                                        stringstoadd = [pathname]
+                        elif n == ARGV_ADD_NEWFILE:
+                                pathname = AskFileForSave()
+                                if pathname:
+                                        stringstoadd = [pathname]
+                        elif n == ARGV_ADD_FOLDER:
+                                pathname = AskFolder()
+                                if pathname:
+                                        stringstoadd = [pathname]
+                        elif n == ARGV_CMDLINE_DATA:
+                                pass # Nothing to do
+                        else:
+                                raise RuntimeError, "Unknown dialog item %d"%n
+
+                        for stringtoadd in stringstoadd:
+                                if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
+                                        stringtoadd = `stringtoadd`
+                                h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
+                                oldstr = GetDialogItemText(h)
+                                if oldstr and oldstr[-1] != ' ':
+                                        oldstr = oldstr + ' '
+                                oldstr = oldstr + stringtoadd
+                                if oldstr[-1] != ' ':
+                                        oldstr = oldstr + ' '
+                                SetDialogItemText(h, oldstr)
+                                d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
+                h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
+                oldstr = GetDialogItemText(h)
+                tmplist = string.split(oldstr)
+                newlist = []
+                while tmplist:
+                        item = tmplist[0]
+                        del tmplist[0]
+                        if item[0] == '"':
+                                while item[-1] != '"':
+                                        if not tmplist:
+                                                raise RuntimeError, "Unterminated quoted argument"
+                                        item = item + ' ' + tmplist[0]
+                                        del tmplist[0]
+                                item = item[1:-1]
+                        if item[0] == "'":
+                                while item[-1] != "'":
+                                        if not tmplist:
+                                                raise RuntimeError, "Unterminated quoted argument"
+                                        item = item + ' ' + tmplist[0]
+                                        del tmplist[0]
+                                item = item[1:-1]
+                        newlist.append(item)
+                return newlist
+        finally:
+                if hasattr(MacOS, 'SchedParams'):
+                        MacOS.SchedParams(*appsw)
+                del d
 
 def _process_Nav_args(dftflags, **args):
-	import aepack
-	import Carbon.AE
-	import Carbon.File
-	for k in args.keys():
-		if args[k] is None:
-			del args[k]
-	# Set some defaults, and modify some arguments
-	if not args.has_key('dialogOptionFlags'):
-		args['dialogOptionFlags'] = dftflags
-	if args.has_key('defaultLocation') and \
-			not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
-		defaultLocation = args['defaultLocation']
-		if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
-			args['defaultLocation'] = aepack.pack(defaultLocation)
-		else:
-			defaultLocation = Carbon.File.FSRef(defaultLocation)
-			args['defaultLocation'] = aepack.pack(defaultLocation)
-	if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
-		typeList = args['typeList'][:]
-		# Workaround for OSX typeless files:
-		if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
-			typeList = typeList + ('\0\0\0\0',)
-		data = 'Pyth' + struct.pack("hh", 0, len(typeList))
-		for type in typeList:
-			data = data+type
-		args['typeList'] = Carbon.Res.Handle(data)
-	tpwanted = str
-	if args.has_key('wanted'):
-		tpwanted = args['wanted']
-		del args['wanted']
-	return args, tpwanted
-	
+        import aepack
+        import Carbon.AE
+        import Carbon.File
+        for k in args.keys():
+                if args[k] is None:
+                        del args[k]
+        # Set some defaults, and modify some arguments
+        if not args.has_key('dialogOptionFlags'):
+                args['dialogOptionFlags'] = dftflags
+        if args.has_key('defaultLocation') and \
+                        not isinstance(args['defaultLocation'], Carbon.AE.AEDesc):
+                defaultLocation = args['defaultLocation']
+                if isinstance(defaultLocation, (Carbon.File.FSSpec, Carbon.File.FSRef)):
+                        args['defaultLocation'] = aepack.pack(defaultLocation)
+                else:
+                        defaultLocation = Carbon.File.FSRef(defaultLocation)
+                        args['defaultLocation'] = aepack.pack(defaultLocation)
+        if args.has_key('typeList') and not isinstance(args['typeList'], Carbon.Res.ResourceType):
+                typeList = args['typeList'][:]
+                # Workaround for OSX typeless files:
+                if 'TEXT' in typeList and not '\0\0\0\0' in typeList:
+                        typeList = typeList + ('\0\0\0\0',)
+                data = 'Pyth' + struct.pack("hh", 0, len(typeList))
+                for type in typeList:
+                        data = data+type
+                args['typeList'] = Carbon.Res.Handle(data)
+        tpwanted = str
+        if args.has_key('wanted'):
+                tpwanted = args['wanted']
+                del args['wanted']
+        return args, tpwanted
+
 def _dummy_Nav_eventproc(msg, data):
-	pass
-	
+        pass
+
 _default_Nav_eventproc = _dummy_Nav_eventproc
 
 def SetDefaultEventProc(proc):
-	global _default_Nav_eventproc
-	rv = _default_Nav_eventproc
-	if proc is None:
-		proc = _dummy_Nav_eventproc
-	_default_Nav_eventproc = proc
-	return rv
-	
+        global _default_Nav_eventproc
+        rv = _default_Nav_eventproc
+        if proc is None:
+                proc = _dummy_Nav_eventproc
+        _default_Nav_eventproc = proc
+        return rv
+
 def AskFileForOpen(
-		message=None,
-		typeList=None,
-		# From here on the order is not documented
-		version=None,
-		defaultLocation=None,
-		dialogOptionFlags=None,
-		location=None,
-		clientName=None,
-		windowTitle=None,
-		actionButtonLabel=None,
-		cancelButtonLabel=None,
-		preferenceKey=None,
-		popupExtension=None,
-		eventProc=_dummy_Nav_eventproc,
-		previewProc=None,
-		filterProc=None,
-		wanted=None,
-		multiple=None):
-	"""Display a dialog asking the user for a file to open.
-	
-	wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
-	the other arguments can be looked up in Apple's Navigation Services documentation"""
-		
-	default_flags = 0x56 # Or 0xe4?
-	args, tpwanted = _process_Nav_args(default_flags, version=version,
-		defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
-		location=location,clientName=clientName,windowTitle=windowTitle,
-		actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
-		message=message,preferenceKey=preferenceKey,
-		popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
-		filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple) 
-	_interact()
-	try:
-		rr = Nav.NavChooseFile(args)
-		good = 1
-	except Nav.error, arg:
-		if arg[0] != -128: # userCancelledErr
-			raise Nav.error, arg
-		return None
-	if not rr.validRecord or not rr.selection:
-		return None
-	if issubclass(tpwanted, Carbon.File.FSRef):
-		return tpwanted(rr.selection_fsr[0])
-	if issubclass(tpwanted, Carbon.File.FSSpec):
-		return tpwanted(rr.selection[0])
-	if issubclass(tpwanted, str):
-		return tpwanted(rr.selection_fsr[0].as_pathname())
-	if issubclass(tpwanted, unicode):
-		return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
-	raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
+                message=None,
+                typeList=None,
+                # From here on the order is not documented
+                version=None,
+                defaultLocation=None,
+                dialogOptionFlags=None,
+                location=None,
+                clientName=None,
+                windowTitle=None,
+                actionButtonLabel=None,
+                cancelButtonLabel=None,
+                preferenceKey=None,
+                popupExtension=None,
+                eventProc=_dummy_Nav_eventproc,
+                previewProc=None,
+                filterProc=None,
+                wanted=None,
+                multiple=None):
+        """Display a dialog asking the user for a file to open.
+
+        wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
+        the other arguments can be looked up in Apple's Navigation Services documentation"""
+
+        default_flags = 0x56 # Or 0xe4?
+        args, tpwanted = _process_Nav_args(default_flags, version=version,
+                defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
+                location=location,clientName=clientName,windowTitle=windowTitle,
+                actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
+                message=message,preferenceKey=preferenceKey,
+                popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc,
+                filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple)
+        _interact()
+        try:
+                rr = Nav.NavChooseFile(args)
+                good = 1
+        except Nav.error, arg:
+                if arg[0] != -128: # userCancelledErr
+                        raise Nav.error, arg
+                return None
+        if not rr.validRecord or not rr.selection:
+                return None
+        if issubclass(tpwanted, Carbon.File.FSRef):
+                return tpwanted(rr.selection_fsr[0])
+        if issubclass(tpwanted, Carbon.File.FSSpec):
+                return tpwanted(rr.selection[0])
+        if issubclass(tpwanted, str):
+                return tpwanted(rr.selection_fsr[0].as_pathname())
+        if issubclass(tpwanted, unicode):
+                return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
+        raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
 
 def AskFileForSave(
-		message=None,
-		savedFileName=None,
-		# From here on the order is not documented
-		version=None,
-		defaultLocation=None,
-		dialogOptionFlags=None,
-		location=None,
-		clientName=None,
-		windowTitle=None,
-		actionButtonLabel=None,
-		cancelButtonLabel=None,
-		preferenceKey=None,
-		popupExtension=None,
-		eventProc=_dummy_Nav_eventproc,
-		fileType=None,
-		fileCreator=None,
-		wanted=None,
-		multiple=None):
-	"""Display a dialog asking the user for a filename to save to.
-	
-	wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
-	the other arguments can be looked up in Apple's Navigation Services documentation"""
-		
+                message=None,
+                savedFileName=None,
+                # From here on the order is not documented
+                version=None,
+                defaultLocation=None,
+                dialogOptionFlags=None,
+                location=None,
+                clientName=None,
+                windowTitle=None,
+                actionButtonLabel=None,
+                cancelButtonLabel=None,
+                preferenceKey=None,
+                popupExtension=None,
+                eventProc=_dummy_Nav_eventproc,
+                fileType=None,
+                fileCreator=None,
+                wanted=None,
+                multiple=None):
+        """Display a dialog asking the user for a filename to save to.
 
-	default_flags = 0x07
-	args, tpwanted = _process_Nav_args(default_flags, version=version,
-		defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
-		location=location,clientName=clientName,windowTitle=windowTitle,
-		actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
-		savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
-		popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
-		fileCreator=fileCreator,wanted=wanted,multiple=multiple) 
-	_interact()
-	try:
-		rr = Nav.NavPutFile(args)
-		good = 1
-	except Nav.error, arg:
-		if arg[0] != -128: # userCancelledErr
-			raise Nav.error, arg
-		return None
-	if not rr.validRecord or not rr.selection:
-		return None
-	if issubclass(tpwanted, Carbon.File.FSRef):
-		raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
-	if issubclass(tpwanted, Carbon.File.FSSpec):
-		return tpwanted(rr.selection[0])
-	if issubclass(tpwanted, (str, unicode)):
-		if sys.platform == 'mac':
-			fullpath = rr.selection[0].as_pathname()
-		else:
-			# This is gross, and probably incorrect too
-			vrefnum, dirid, name = rr.selection[0].as_tuple()
-			pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
-			pardir_fsr = Carbon.File.FSRef(pardir_fss)
-			pardir_path = pardir_fsr.FSRefMakePath()  # This is utf-8
-			name_utf8 = unicode(name, 'macroman').encode('utf8')
-			fullpath = os.path.join(pardir_path, name_utf8)
-		if issubclass(tpwanted, unicode):
-			return unicode(fullpath, 'utf8')
-		return tpwanted(fullpath)
-	raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
-		
+        wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
+        the other arguments can be looked up in Apple's Navigation Services documentation"""
+
+
+        default_flags = 0x07
+        args, tpwanted = _process_Nav_args(default_flags, version=version,
+                defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
+                location=location,clientName=clientName,windowTitle=windowTitle,
+                actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
+                savedFileName=savedFileName,message=message,preferenceKey=preferenceKey,
+                popupExtension=popupExtension,eventProc=eventProc,fileType=fileType,
+                fileCreator=fileCreator,wanted=wanted,multiple=multiple)
+        _interact()
+        try:
+                rr = Nav.NavPutFile(args)
+                good = 1
+        except Nav.error, arg:
+                if arg[0] != -128: # userCancelledErr
+                        raise Nav.error, arg
+                return None
+        if not rr.validRecord or not rr.selection:
+                return None
+        if issubclass(tpwanted, Carbon.File.FSRef):
+                raise TypeError, "Cannot pass wanted=FSRef to AskFileForSave"
+        if issubclass(tpwanted, Carbon.File.FSSpec):
+                return tpwanted(rr.selection[0])
+        if issubclass(tpwanted, (str, unicode)):
+                if sys.platform == 'mac':
+                        fullpath = rr.selection[0].as_pathname()
+                else:
+                        # This is gross, and probably incorrect too
+                        vrefnum, dirid, name = rr.selection[0].as_tuple()
+                        pardir_fss = Carbon.File.FSSpec((vrefnum, dirid, ''))
+                        pardir_fsr = Carbon.File.FSRef(pardir_fss)
+                        pardir_path = pardir_fsr.FSRefMakePath()  # This is utf-8
+                        name_utf8 = unicode(name, 'macroman').encode('utf8')
+                        fullpath = os.path.join(pardir_path, name_utf8)
+                if issubclass(tpwanted, unicode):
+                        return unicode(fullpath, 'utf8')
+                return tpwanted(fullpath)
+        raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
+
 def AskFolder(
-		message=None,
-		# From here on the order is not documented
-		version=None,
-		defaultLocation=None,
-		dialogOptionFlags=None,
-		location=None,
-		clientName=None,
-		windowTitle=None,
-		actionButtonLabel=None,
-		cancelButtonLabel=None,
-		preferenceKey=None,
-		popupExtension=None,
-		eventProc=_dummy_Nav_eventproc,
-		filterProc=None,
-		wanted=None,
-		multiple=None):
-	"""Display a dialog asking the user for select a folder.
-	
-	wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
-	the other arguments can be looked up in Apple's Navigation Services documentation"""
-		
-	default_flags = 0x17
-	args, tpwanted = _process_Nav_args(default_flags, version=version,
-		defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
-		location=location,clientName=clientName,windowTitle=windowTitle,
-		actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
-		message=message,preferenceKey=preferenceKey,
-		popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
-		wanted=wanted,multiple=multiple) 
-	_interact()
-	try:
-		rr = Nav.NavChooseFolder(args)
-		good = 1
-	except Nav.error, arg:
-		if arg[0] != -128: # userCancelledErr
-			raise Nav.error, arg
-		return None
-	if not rr.validRecord or not rr.selection:
-		return None
-	if issubclass(tpwanted, Carbon.File.FSRef):
-		return tpwanted(rr.selection_fsr[0])
-	if issubclass(tpwanted, Carbon.File.FSSpec):
-		return tpwanted(rr.selection[0])
-	if issubclass(tpwanted, str):
-		return tpwanted(rr.selection_fsr[0].as_pathname())
-	if issubclass(tpwanted, unicode):
-		return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
-	raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
-	
+                message=None,
+                # From here on the order is not documented
+                version=None,
+                defaultLocation=None,
+                dialogOptionFlags=None,
+                location=None,
+                clientName=None,
+                windowTitle=None,
+                actionButtonLabel=None,
+                cancelButtonLabel=None,
+                preferenceKey=None,
+                popupExtension=None,
+                eventProc=_dummy_Nav_eventproc,
+                filterProc=None,
+                wanted=None,
+                multiple=None):
+        """Display a dialog asking the user for select a folder.
+
+        wanted is the return type wanted: FSSpec, FSRef, unicode or string (default)
+        the other arguments can be looked up in Apple's Navigation Services documentation"""
+
+        default_flags = 0x17
+        args, tpwanted = _process_Nav_args(default_flags, version=version,
+                defaultLocation=defaultLocation, dialogOptionFlags=dialogOptionFlags,
+                location=location,clientName=clientName,windowTitle=windowTitle,
+                actionButtonLabel=actionButtonLabel,cancelButtonLabel=cancelButtonLabel,
+                message=message,preferenceKey=preferenceKey,
+                popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc,
+                wanted=wanted,multiple=multiple)
+        _interact()
+        try:
+                rr = Nav.NavChooseFolder(args)
+                good = 1
+        except Nav.error, arg:
+                if arg[0] != -128: # userCancelledErr
+                        raise Nav.error, arg
+                return None
+        if not rr.validRecord or not rr.selection:
+                return None
+        if issubclass(tpwanted, Carbon.File.FSRef):
+                return tpwanted(rr.selection_fsr[0])
+        if issubclass(tpwanted, Carbon.File.FSSpec):
+                return tpwanted(rr.selection[0])
+        if issubclass(tpwanted, str):
+                return tpwanted(rr.selection_fsr[0].as_pathname())
+        if issubclass(tpwanted, unicode):
+                return tpwanted(rr.selection_fsr[0].as_pathname(), 'utf8')
+        raise TypeError, "Unknown value for argument 'wanted': %s" % repr(tpwanted)
+
 
 def test():
-	import time
+        import time
 
-	Message("Testing EasyDialogs.")
-	optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'), 
-				('flags=', 'Valued option'), ('f:', 'Short valued option'))
-	commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
-	argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
-	Message("Command line: %s"%' '.join(argv))
-	for i in range(len(argv)):
-		print 'arg[%d] = %s'%(i, `argv[i]`)
-	ok = AskYesNoCancel("Do you want to proceed?")
-	ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
-	if ok > 0:
-		s = AskString("Enter your first name", "Joe")
-		s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
-		if not s2:
-			Message("%s has no secret nickname"%s)
-		else:
-			Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
-	else:
-		s = 'Anonymous'
-	rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
-	Message("rv: %s"%rv)
-	rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
-	Message("rv.as_pathname: %s"%rv.as_pathname())
-	rv = AskFolder()
-	Message("Folder name: %s"%rv)
-	text = ( "Working Hard...", "Hardly Working..." ,
-			"So far, so good!", "Keep on truckin'" )
-	bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
-	try:
-		if hasattr(MacOS, 'SchedParams'):
-			appsw = MacOS.SchedParams(1, 0)
-		for i in xrange(20):
-			bar.inc()
-			time.sleep(0.05)
-		bar.set(0,100)
-		for i in xrange(100):
-			bar.set(i)
-			time.sleep(0.05)
-			if i % 10 == 0:
-				bar.label(text[(i/10) % 4])
-		bar.label("Done.")
-		time.sleep(1.0) 	# give'em a chance to see "Done."
-	finally:
-		del bar
-		if hasattr(MacOS, 'SchedParams'):
-			apply(MacOS.SchedParams, appsw)
+        Message("Testing EasyDialogs.")
+        optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
+                                ('flags=', 'Valued option'), ('f:', 'Short valued option'))
+        commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
+        argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
+        Message("Command line: %s"%' '.join(argv))
+        for i in range(len(argv)):
+                print 'arg[%d] = %s'%(i, `argv[i]`)
+        ok = AskYesNoCancel("Do you want to proceed?")
+        ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
+        if ok > 0:
+                s = AskString("Enter your first name", "Joe")
+                s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
+                if not s2:
+                        Message("%s has no secret nickname"%s)
+                else:
+                        Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
+        else:
+                s = 'Anonymous'
+        rv = AskFileForOpen(message="Gimme a file, %s"%s, wanted=Carbon.File.FSSpec)
+        Message("rv: %s"%rv)
+        rv = AskFileForSave(wanted=Carbon.File.FSRef, savedFileName="%s.txt"%s)
+        Message("rv.as_pathname: %s"%rv.as_pathname())
+        rv = AskFolder()
+        Message("Folder name: %s"%rv)
+        text = ( "Working Hard...", "Hardly Working..." ,
+                        "So far, so good!", "Keep on truckin'" )
+        bar = ProgressBar("Progress, progress...", 0, label="Ramping up...")
+        try:
+                if hasattr(MacOS, 'SchedParams'):
+                        appsw = MacOS.SchedParams(1, 0)
+                for i in xrange(20):
+                        bar.inc()
+                        time.sleep(0.05)
+                bar.set(0,100)
+                for i in xrange(100):
+                        bar.set(i)
+                        time.sleep(0.05)
+                        if i % 10 == 0:
+                                bar.label(text[(i/10) % 4])
+                bar.label("Done.")
+                time.sleep(1.0)         # give'em a chance to see "Done."
+        finally:
+                del bar
+                if hasattr(MacOS, 'SchedParams'):
+                        MacOS.SchedParams(*appsw)
 
 if __name__ == '__main__':
-	try:
-		test()
-	except KeyboardInterrupt:
-		Message("Operation Canceled.")
+        try:
+                test()
+        except KeyboardInterrupt:
+                Message("Operation Canceled.")
 
diff --git a/Lib/plat-mac/FrameWork.py b/Lib/plat-mac/FrameWork.py
index f465d84..8eec4b8 100644
--- a/Lib/plat-mac/FrameWork.py
+++ b/Lib/plat-mac/FrameWork.py
@@ -29,12 +29,12 @@
 import EasyDialogs
 
 try:
-	MyFrontWindow = FrontNonFloatingWindow
+        MyFrontWindow = FrontNonFloatingWindow
 except NameError:
-	MyFrontWindow = FrontWindow
+        MyFrontWindow = FrontWindow
 
-kHighLevelEvent = 23	# Don't know what header file this should come from
-SCROLLBARWIDTH = 16		# Again, not a clue...
+kHighLevelEvent = 23    # Don't know what header file this should come from
+SCROLLBARWIDTH = 16             # Again, not a clue...
 
 # Trick to forestall a set of SIOUX menus being added to our menubar
 SIOUX_APPLEMENU_ID=32000
@@ -67,1057 +67,1057 @@
 
 #
 # The useable portion of the screen
-#	## but what happens with multiple screens? jvr
+#       ## but what happens with multiple screens? jvr
 screenbounds = GetQDGlobalsScreenBits().bounds
 screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
-	screenbounds[2]-4, screenbounds[3]-4
-	
-next_window_x = 16		# jvr
-next_window_y = 44		# jvr
+        screenbounds[2]-4, screenbounds[3]-4
+
+next_window_x = 16              # jvr
+next_window_y = 44              # jvr
 
 def windowbounds(width, height):
-	"Return sensible window bounds"
-	global next_window_x, next_window_y
-	r, b = next_window_x+width, next_window_y+height
-	if r > screenbounds[2]:
-		next_window_x = 16
-	if b > screenbounds[3]:
-		next_window_y = 44
-	l, t = next_window_x, next_window_y
-	r, b = next_window_x+width, next_window_y+height
-	next_window_x, next_window_y = next_window_x + 8, next_window_y + 20	# jvr
-	return l, t, r, b
+        "Return sensible window bounds"
+        global next_window_x, next_window_y
+        r, b = next_window_x+width, next_window_y+height
+        if r > screenbounds[2]:
+                next_window_x = 16
+        if b > screenbounds[3]:
+                next_window_y = 44
+        l, t = next_window_x, next_window_y
+        r, b = next_window_x+width, next_window_y+height
+        next_window_x, next_window_y = next_window_x + 8, next_window_y + 20    # jvr
+        return l, t, r, b
 
 _watch = None
 def setwatchcursor():
-	global _watch
-	
-	if _watch == None:
-		_watch = GetCursor(4).data
-	SetCursor(_watch)
-	
+        global _watch
+
+        if _watch == None:
+                _watch = GetCursor(4).data
+        SetCursor(_watch)
+
 def setarrowcursor():
-	SetCursor(GetQDGlobalsArrow())
+        SetCursor(GetQDGlobalsArrow())
 
 class Application:
-	
-	"Application framework -- your application should be a derived class"
-	
-	def __init__(self, nomenubar=0):
-		self._doing_asyncevents = 0
-		self.quitting = 0
-		self.needmenubarredraw = 0
-		self._windows = {}
-		self._helpmenu = None
-		if nomenubar:
-			self.menubar = None
-		else:
-			self.makemenubar()
-			
-	def __del__(self):
-		if self._doing_asyncevents:
-			self._doing_asyncevents = 0
-			MacOS.SetEventHandler()
-	
-	def makemenubar(self):
-		self.menubar = MenuBar(self)
-		AppleMenu(self.menubar, self.getabouttext(), self.do_about)
-		self.makeusermenus()
 
-	def makeusermenus(self):
-		self.filemenu = m = Menu(self.menubar, "File")
-		self._quititem = MenuItem(m, "Quit", "Q", self._quit)
-		
-	def gethelpmenu(self):
-		if self._helpmenu == None:
-			self._helpmenu = HelpMenu(self.menubar)
-		return self._helpmenu
-	
-	def _quit(self, *args):
-		self.quitting = 1
-		
-	def cleanup(self):
-		for w in self._windows.values():
-			w.do_close()
-		return self._windows == {}
-		
-	def appendwindow(self, wid, window):
-		self._windows[wid] = window
-		
-	def removewindow(self, wid):
-		del self._windows[wid]
-	
-	def getabouttext(self):
-		return "About %s..." % self.__class__.__name__
-	
-	def do_about(self, id, item, window, event):
-		EasyDialogs.Message("Hello, world!" + "\015(%s)" % self.__class__.__name__)
-	
-	# The main event loop is broken up in several simple steps.
-	# This is done so you can override each individual part,
-	# if you have a need to do extra processing independent of the
-	# event type.
-	# Normally, however, you'd just define handlers for individual
-	# events.
-	
-	schedparams = (0, 0)	# By default disable Python's event handling
-	default_wait = None		# By default we wait GetCaretTime in WaitNextEvent
-	
-	def mainloop(self, mask = everyEvent, wait = None):
-		self.quitting = 0
-		if hasattr(MacOS, 'SchedParams'):
-			saveparams = apply(MacOS.SchedParams, self.schedparams)
-		try:
-			while not self.quitting:
-				try:
-					self.do1event(mask, wait)
-				except (Application, SystemExit):
-					# Note: the raising of "self" is old-fashioned idiom to
-					# exit the mainloop. Calling _quit() is better for new
-					# applications.
-					break
-		finally:
-			if hasattr(MacOS, 'SchedParams'):
-				apply(MacOS.SchedParams, saveparams)
-	
-	def dopendingevents(self, mask = everyEvent):
-		"""dopendingevents - Handle all pending events"""
-		while self.do1event(mask, wait=0):
-			pass
-	
-	def do1event(self, mask = everyEvent, wait = None):
-		ok, event = self.getevent(mask, wait)
-		if IsDialogEvent(event):
-			if self.do_dialogevent(event):
-				return
-		if ok:
-			self.dispatch(event)
-		else:
-			self.idle(event)
-			
-	def idle(self, event):
-		pass
-	
-	def getevent(self, mask = everyEvent, wait = None):
-		if self.needmenubarredraw:
-			DrawMenuBar()
-			self.needmenubarredraw = 0
-		if wait is None:
-			wait = self.default_wait
-			if wait is None:
-				wait = GetCaretTime()
-		ok, event = WaitNextEvent(mask, wait)
-		return ok, event
-			
-	def dispatch(self, event):
-		# The following appears to be double work (already done in do1event)
-		# but we need it for asynchronous event handling
-		if IsDialogEvent(event):
-			if self.do_dialogevent(event):
-				return
-		(what, message, when, where, modifiers) = event
-		if eventname.has_key(what):
-			name = "do_" + eventname[what]
-		else:
-			name = "do_%d" % what
-		try:
-			handler = getattr(self, name)
-		except AttributeError:
-			handler = self.do_unknownevent
-		handler(event)
-		
-	def asyncevents(self, onoff):
-		"""asyncevents - Set asynchronous event handling on or off"""
-		if MacOS.runtimemodel == 'macho':
-			raise 'Unsupported in MachoPython'
-		old = self._doing_asyncevents
-		if old:
-			MacOS.SetEventHandler()
-			apply(MacOS.SchedParams, self.schedparams)
-		if onoff:
-			MacOS.SetEventHandler(self.dispatch)
-			doint, dummymask, benice, howoften, bgyield = \
-			       self.schedparams
-			MacOS.SchedParams(doint, everyEvent, benice,
-					  howoften, bgyield)
-		self._doing_asyncevents = onoff
-		return old
-			
-	def do_dialogevent(self, event):
-		gotone, dlg, item = DialogSelect(event)
-		if gotone:
-			window = dlg.GetDialogWindow()
-			if self._windows.has_key(window):
-				self._windows[window].do_itemhit(item, event)
-			else:
-				print 'Dialog event for unknown dialog'
-			return 1
-		return 0
-	
-	def do_mouseDown(self, event):
-		(what, message, when, where, modifiers) = event
-		partcode, wid = FindWindow(where)
+        "Application framework -- your application should be a derived class"
 
-		#
-		# Find the correct name.
-		#
-		if partname.has_key(partcode):
-			name = "do_" + partname[partcode]
-		else:
-			name = "do_%d" % partcode
+        def __init__(self, nomenubar=0):
+                self._doing_asyncevents = 0
+                self.quitting = 0
+                self.needmenubarredraw = 0
+                self._windows = {}
+                self._helpmenu = None
+                if nomenubar:
+                        self.menubar = None
+                else:
+                        self.makemenubar()
 
-		if wid == None:
-			# No window, or a non-python window	
-			try:
-				handler = getattr(self, name)
-			except AttributeError:
-				# Not menubar or something, so assume someone
-				# else's window
-				if hasattr(MacOS, 'HandleEvent'):
-					MacOS.HandleEvent(event)
-				return		
-		elif self._windows.has_key(wid):
-			# It is a window. Hand off to correct window.
-			window = self._windows[wid]
-			try:
-				handler = getattr(window, name)
-			except AttributeError:
-				handler = self.do_unknownpartcode
-		else:
-			# It is a python-toolbox window, but not ours.
-			handler = self.do_unknownwindow
-		handler(partcode, wid, event)
+        def __del__(self):
+                if self._doing_asyncevents:
+                        self._doing_asyncevents = 0
+                        MacOS.SetEventHandler()
 
-	def do_inSysWindow(self, partcode, window, event):
-		if hasattr(MacOS, 'HandleEvent'):
-			MacOS.HandleEvent(event)
-	
-	def do_inDesk(self, partcode, window, event):
-		if hasattr(MacOS, 'HandleEvent'):
-			MacOS.HandleEvent(event)
-	
-	def do_inMenuBar(self, partcode, window, event):
-		if not self.menubar:
-			if hasattr(MacOS, 'HandleEvent'):
-				MacOS.HandleEvent(event)
-			return
-		(what, message, when, where, modifiers) = event
-		result = MenuSelect(where)
-		id = (result>>16) & 0xffff	# Hi word
-		if id >= 0x8000:
-			id = -65536 + id
-		item = result & 0xffff		# Lo word
-		self.do_rawmenu(id, item, window, event)
-	
-	def do_rawmenu(self, id, item, window, event):
-		try:
-			self.do_menu(id, item, window, event)
-		finally:
-			HiliteMenu(0)
-	
-	def do_menu(self, id, item, window, event):
-		if hasattr(MacOS, 'OutputSeen'):
-			MacOS.OutputSeen()
-		self.menubar.dispatch(id, item, window, event)
-	
-	
-	def do_unknownpartcode(self, partcode, window, event):
-		(what, message, when, where, modifiers) = event
-		if DEBUG: print "Mouse down at global:", where
-		if DEBUG: print "\tUnknown part code:", partcode
-		if DEBUG: print "\tEvent:", self.printevent(event)
-		if hasattr(MacOS, 'HandleEvent'):
-			MacOS.HandleEvent(event)
-		
-	def do_unknownwindow(self, partcode, window, event):
-		if DEBUG: print 'Unknown window:', window
-		if hasattr(MacOS, 'HandleEvent'):
-			MacOS.HandleEvent(event)
-	
-	def do_keyDown(self, event):
-		self.do_key(event)
-	
-	def do_autoKey(self, event):
-		if not event[-1] & cmdKey:
-			self.do_key(event)
-	
-	def do_key(self, event):
-		(what, message, when, where, modifiers) = event
-		c = chr(message & charCodeMask)
-		if self.menubar:
-			result = MenuEvent(event)
-			id = (result>>16) & 0xffff	# Hi word
-			item = result & 0xffff		# Lo word
-			if id:
-				self.do_rawmenu(id, item, None, event)
-				return
-			# Otherwise we fall-through
-		if modifiers & cmdKey:
-			if c == '.':
-				raise self
-			else:
-				if not self.menubar:
-					if hasattr(MacOS, 'HandleEvent'):
-						MacOS.HandleEvent(event)
-				return
-		else:
-			# See whether the front window wants it
-			w = MyFrontWindow()
-			if w and self._windows.has_key(w):
-				window = self._windows[w]
-				try:
-					do_char = window.do_char
-				except AttributeError:
-					do_char = self.do_char
-				do_char(c, event)
-			# else it wasn't for us, sigh...
-	
-	def do_char(self, c, event):
-		if DEBUG: print "Character", `c`
-	
-	def do_updateEvt(self, event):
-		(what, message, when, where, modifiers) = event
-		wid = WhichWindow(message)
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			window.do_rawupdate(wid, event)
-		else:
-			if hasattr(MacOS, 'HandleEvent'):
-				MacOS.HandleEvent(event)
-	
-	def do_activateEvt(self, event):
-		(what, message, when, where, modifiers) = event
-		wid = WhichWindow(message)
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			window.do_activate(modifiers & 1, event)
-		else:
-			if hasattr(MacOS, 'HandleEvent'):
-				MacOS.HandleEvent(event)
-	
-	def do_osEvt(self, event):
-		(what, message, when, where, modifiers) = event
-		which = (message >> 24) & 0xff
-		if which == 1:	# suspend/resume
-			self.do_suspendresume(event)
-		else:
-			if DEBUG:
-				print 'unknown osEvt:',
-				self.printevent(event)
-	
-	def do_suspendresume(self, event):
-		(what, message, when, where, modifiers) = event
-		wid = MyFrontWindow()
-		if wid and self._windows.has_key(wid):
-			window = self._windows[wid]
-			window.do_activate(message & 1, event)
-	
-	def do_kHighLevelEvent(self, event):
-		(what, message, when, where, modifiers) = event
-		if DEBUG: 
-			print "High Level Event:",
-			self.printevent(event)
-		try:
-			AEProcessAppleEvent(event)
-		except:
-			pass
-			#print "AEProcessAppleEvent error:"
-			#traceback.print_exc()
-	
-	def do_unknownevent(self, event):
-		if DEBUG:
-			print "Unhandled event:",
-			self.printevent(event)
-	
-	def printevent(self, event):
-		(what, message, when, where, modifiers) = event
-		nicewhat = `what`
-		if eventname.has_key(what):
-			nicewhat = eventname[what]
-		print nicewhat,
-		if what == kHighLevelEvent:
-			h, v = where
-			print `ostypecode(message)`, hex(when), `ostypecode(h | (v<<16))`,
-		else:
-			print hex(message), hex(when), where,
-		print hex(modifiers)
+        def makemenubar(self):
+                self.menubar = MenuBar(self)
+                AppleMenu(self.menubar, self.getabouttext(), self.do_about)
+                self.makeusermenus()
+
+        def makeusermenus(self):
+                self.filemenu = m = Menu(self.menubar, "File")
+                self._quititem = MenuItem(m, "Quit", "Q", self._quit)
+
+        def gethelpmenu(self):
+                if self._helpmenu == None:
+                        self._helpmenu = HelpMenu(self.menubar)
+                return self._helpmenu
+
+        def _quit(self, *args):
+                self.quitting = 1
+
+        def cleanup(self):
+                for w in self._windows.values():
+                        w.do_close()
+                return self._windows == {}
+
+        def appendwindow(self, wid, window):
+                self._windows[wid] = window
+
+        def removewindow(self, wid):
+                del self._windows[wid]
+
+        def getabouttext(self):
+                return "About %s..." % self.__class__.__name__
+
+        def do_about(self, id, item, window, event):
+                EasyDialogs.Message("Hello, world!" + "\015(%s)" % self.__class__.__name__)
+
+        # The main event loop is broken up in several simple steps.
+        # This is done so you can override each individual part,
+        # if you have a need to do extra processing independent of the
+        # event type.
+        # Normally, however, you'd just define handlers for individual
+        # events.
+
+        schedparams = (0, 0)    # By default disable Python's event handling
+        default_wait = None             # By default we wait GetCaretTime in WaitNextEvent
+
+        def mainloop(self, mask = everyEvent, wait = None):
+                self.quitting = 0
+                if hasattr(MacOS, 'SchedParams'):
+                        saveparams = MacOS.SchedParams(*self.schedparams)
+                try:
+                        while not self.quitting:
+                                try:
+                                        self.do1event(mask, wait)
+                                except (Application, SystemExit):
+                                        # Note: the raising of "self" is old-fashioned idiom to
+                                        # exit the mainloop. Calling _quit() is better for new
+                                        # applications.
+                                        break
+                finally:
+                        if hasattr(MacOS, 'SchedParams'):
+                                MacOS.SchedParams(*saveparams)
+
+        def dopendingevents(self, mask = everyEvent):
+                """dopendingevents - Handle all pending events"""
+                while self.do1event(mask, wait=0):
+                        pass
+
+        def do1event(self, mask = everyEvent, wait = None):
+                ok, event = self.getevent(mask, wait)
+                if IsDialogEvent(event):
+                        if self.do_dialogevent(event):
+                                return
+                if ok:
+                        self.dispatch(event)
+                else:
+                        self.idle(event)
+
+        def idle(self, event):
+                pass
+
+        def getevent(self, mask = everyEvent, wait = None):
+                if self.needmenubarredraw:
+                        DrawMenuBar()
+                        self.needmenubarredraw = 0
+                if wait is None:
+                        wait = self.default_wait
+                        if wait is None:
+                                wait = GetCaretTime()
+                ok, event = WaitNextEvent(mask, wait)
+                return ok, event
+
+        def dispatch(self, event):
+                # The following appears to be double work (already done in do1event)
+                # but we need it for asynchronous event handling
+                if IsDialogEvent(event):
+                        if self.do_dialogevent(event):
+                                return
+                (what, message, when, where, modifiers) = event
+                if eventname.has_key(what):
+                        name = "do_" + eventname[what]
+                else:
+                        name = "do_%d" % what
+                try:
+                        handler = getattr(self, name)
+                except AttributeError:
+                        handler = self.do_unknownevent
+                handler(event)
+
+        def asyncevents(self, onoff):
+                """asyncevents - Set asynchronous event handling on or off"""
+                if MacOS.runtimemodel == 'macho':
+                        raise 'Unsupported in MachoPython'
+                old = self._doing_asyncevents
+                if old:
+                        MacOS.SetEventHandler()
+                        MacOS.SchedParams(*self.schedparams)
+                if onoff:
+                        MacOS.SetEventHandler(self.dispatch)
+                        doint, dummymask, benice, howoften, bgyield = \
+                               self.schedparams
+                        MacOS.SchedParams(doint, everyEvent, benice,
+                                          howoften, bgyield)
+                self._doing_asyncevents = onoff
+                return old
+
+        def do_dialogevent(self, event):
+                gotone, dlg, item = DialogSelect(event)
+                if gotone:
+                        window = dlg.GetDialogWindow()
+                        if self._windows.has_key(window):
+                                self._windows[window].do_itemhit(item, event)
+                        else:
+                                print 'Dialog event for unknown dialog'
+                        return 1
+                return 0
+
+        def do_mouseDown(self, event):
+                (what, message, when, where, modifiers) = event
+                partcode, wid = FindWindow(where)
+
+                #
+                # Find the correct name.
+                #
+                if partname.has_key(partcode):
+                        name = "do_" + partname[partcode]
+                else:
+                        name = "do_%d" % partcode
+
+                if wid == None:
+                        # No window, or a non-python window
+                        try:
+                                handler = getattr(self, name)
+                        except AttributeError:
+                                # Not menubar or something, so assume someone
+                                # else's window
+                                if hasattr(MacOS, 'HandleEvent'):
+                                        MacOS.HandleEvent(event)
+                                return
+                elif self._windows.has_key(wid):
+                        # It is a window. Hand off to correct window.
+                        window = self._windows[wid]
+                        try:
+                                handler = getattr(window, name)
+                        except AttributeError:
+                                handler = self.do_unknownpartcode
+                else:
+                        # It is a python-toolbox window, but not ours.
+                        handler = self.do_unknownwindow
+                handler(partcode, wid, event)
+
+        def do_inSysWindow(self, partcode, window, event):
+                if hasattr(MacOS, 'HandleEvent'):
+                        MacOS.HandleEvent(event)
+
+        def do_inDesk(self, partcode, window, event):
+                if hasattr(MacOS, 'HandleEvent'):
+                        MacOS.HandleEvent(event)
+
+        def do_inMenuBar(self, partcode, window, event):
+                if not self.menubar:
+                        if hasattr(MacOS, 'HandleEvent'):
+                                MacOS.HandleEvent(event)
+                        return
+                (what, message, when, where, modifiers) = event
+                result = MenuSelect(where)
+                id = (result>>16) & 0xffff      # Hi word
+                if id >= 0x8000:
+                        id = -65536 + id
+                item = result & 0xffff          # Lo word
+                self.do_rawmenu(id, item, window, event)
+
+        def do_rawmenu(self, id, item, window, event):
+                try:
+                        self.do_menu(id, item, window, event)
+                finally:
+                        HiliteMenu(0)
+
+        def do_menu(self, id, item, window, event):
+                if hasattr(MacOS, 'OutputSeen'):
+                        MacOS.OutputSeen()
+                self.menubar.dispatch(id, item, window, event)
+
+
+        def do_unknownpartcode(self, partcode, window, event):
+                (what, message, when, where, modifiers) = event
+                if DEBUG: print "Mouse down at global:", where
+                if DEBUG: print "\tUnknown part code:", partcode
+                if DEBUG: print "\tEvent:", self.printevent(event)
+                if hasattr(MacOS, 'HandleEvent'):
+                        MacOS.HandleEvent(event)
+
+        def do_unknownwindow(self, partcode, window, event):
+                if DEBUG: print 'Unknown window:', window
+                if hasattr(MacOS, 'HandleEvent'):
+                        MacOS.HandleEvent(event)
+
+        def do_keyDown(self, event):
+                self.do_key(event)
+
+        def do_autoKey(self, event):
+                if not event[-1] & cmdKey:
+                        self.do_key(event)
+
+        def do_key(self, event):
+                (what, message, when, where, modifiers) = event
+                c = chr(message & charCodeMask)
+                if self.menubar:
+                        result = MenuEvent(event)
+                        id = (result>>16) & 0xffff      # Hi word
+                        item = result & 0xffff          # Lo word
+                        if id:
+                                self.do_rawmenu(id, item, None, event)
+                                return
+                        # Otherwise we fall-through
+                if modifiers & cmdKey:
+                        if c == '.':
+                                raise self
+                        else:
+                                if not self.menubar:
+                                        if hasattr(MacOS, 'HandleEvent'):
+                                                MacOS.HandleEvent(event)
+                                return
+                else:
+                        # See whether the front window wants it
+                        w = MyFrontWindow()
+                        if w and self._windows.has_key(w):
+                                window = self._windows[w]
+                                try:
+                                        do_char = window.do_char
+                                except AttributeError:
+                                        do_char = self.do_char
+                                do_char(c, event)
+                        # else it wasn't for us, sigh...
+
+        def do_char(self, c, event):
+                if DEBUG: print "Character", `c`
+
+        def do_updateEvt(self, event):
+                (what, message, when, where, modifiers) = event
+                wid = WhichWindow(message)
+                if wid and self._windows.has_key(wid):
+                        window = self._windows[wid]
+                        window.do_rawupdate(wid, event)
+                else:
+                        if hasattr(MacOS, 'HandleEvent'):
+                                MacOS.HandleEvent(event)
+
+        def do_activateEvt(self, event):
+                (what, message, when, where, modifiers) = event
+                wid = WhichWindow(message)
+                if wid and self._windows.has_key(wid):
+                        window = self._windows[wid]
+                        window.do_activate(modifiers & 1, event)
+                else:
+                        if hasattr(MacOS, 'HandleEvent'):
+                                MacOS.HandleEvent(event)
+
+        def do_osEvt(self, event):
+                (what, message, when, where, modifiers) = event
+                which = (message >> 24) & 0xff
+                if which == 1:  # suspend/resume
+                        self.do_suspendresume(event)
+                else:
+                        if DEBUG:
+                                print 'unknown osEvt:',
+                                self.printevent(event)
+
+        def do_suspendresume(self, event):
+                (what, message, when, where, modifiers) = event
+                wid = MyFrontWindow()
+                if wid and self._windows.has_key(wid):
+                        window = self._windows[wid]
+                        window.do_activate(message & 1, event)
+
+        def do_kHighLevelEvent(self, event):
+                (what, message, when, where, modifiers) = event
+                if DEBUG:
+                        print "High Level Event:",
+                        self.printevent(event)
+                try:
+                        AEProcessAppleEvent(event)
+                except:
+                        pass
+                        #print "AEProcessAppleEvent error:"
+                        #traceback.print_exc()
+
+        def do_unknownevent(self, event):
+                if DEBUG:
+                        print "Unhandled event:",
+                        self.printevent(event)
+
+        def printevent(self, event):
+                (what, message, when, where, modifiers) = event
+                nicewhat = `what`
+                if eventname.has_key(what):
+                        nicewhat = eventname[what]
+                print nicewhat,
+                if what == kHighLevelEvent:
+                        h, v = where
+                        print `ostypecode(message)`, hex(when), `ostypecode(h | (v<<16))`,
+                else:
+                        print hex(message), hex(when), where,
+                print hex(modifiers)
 
 
 class MenuBar:
-	"""Represent a set of menus in a menu bar.
-	
-	Interface:
-	
-	- (constructor)
-	- (destructor)
-	- addmenu
-	- addpopup (normally used internally)
-	- dispatch (called from Application)
-	"""
-	
-	nextid = 1	# Necessarily a class variable
-	
-	def getnextid(self):
-		id = MenuBar.nextid
-		MenuBar.nextid = id+1
-		return id
-	
-	def __init__(self, parent=None):
-		self.parent = parent
-		ClearMenuBar()
-		self.bar = GetMenuBar()
-		self.menus = {}
-	
-	# XXX necessary?
-	def close(self):
-		self.parent = None
-		self.bar = None
-		self.menus = None
-	
-	def addmenu(self, title, after = 0, id=None):
-		if id == None:
-			id = self.getnextid()
-		if DEBUG: print 'Newmenu', title, id # XXXX
-		m = NewMenu(id, title)
-		m.InsertMenu(after)
-		if after >= 0:
-			if self.parent:
-				self.parent.needmenubarredraw = 1
-			else:
-				DrawMenuBar()
-		return id, m
-		
-	def delmenu(self, id):
-		if DEBUG: print 'Delmenu', id # XXXX
-		DeleteMenu(id)
-	
-	def addpopup(self, title = ''):
-		return self.addmenu(title, -1)
+        """Represent a set of menus in a menu bar.
 
-# Useless:	
-#	def install(self):
-#		if not self.bar: return
-#		SetMenuBar(self.bar)
-#		if self.parent:
-#			self.parent.needmenubarredraw = 1
-#		else:
-#			DrawMenuBar()
-	
-	def fixmenudimstate(self):
-		for m in self.menus.keys():
-			menu = self.menus[m]
-			if menu.__class__ == FrameWork.AppleMenu:
-				continue
-			for i in range(len(menu.items)):
-				label, shortcut, callback, kind = menu.items[i]
-				if type(callback) == types.StringType:
-					wid = MyFrontWindow()
-					if wid and self.parent._windows.has_key(wid):
-						window = self.parent._windows[wid]
-						if hasattr(window, "domenu_" + callback):
-							menu.menu.EnableMenuItem(i + 1)
-						elif hasattr(self.parent, "domenu_" + callback):
-							menu.menu.EnableMenuItem(i + 1)
-						else:
-							menu.menu.DisableMenuItem(i + 1)
-					elif hasattr(self.parent, "domenu_" + callback):
-						menu.menu.EnableMenuItem(i + 1)
-					else:
-						menu.menu.DisableMenuItem(i + 1)
-				elif callback:
-					pass
-					
-	def dispatch(self, id, item, window, event):
-		if self.menus.has_key(id):
-			self.menus[id].dispatch(id, item, window, event)
-		else:
-			if DEBUG: print "MenuBar.dispatch(%d, %d, %s, %s)" % \
-				(id, item, window, event)
-	
+        Interface:
+
+        - (constructor)
+        - (destructor)
+        - addmenu
+        - addpopup (normally used internally)
+        - dispatch (called from Application)
+        """
+
+        nextid = 1      # Necessarily a class variable
+
+        def getnextid(self):
+                id = MenuBar.nextid
+                MenuBar.nextid = id+1
+                return id
+
+        def __init__(self, parent=None):
+                self.parent = parent
+                ClearMenuBar()
+                self.bar = GetMenuBar()
+                self.menus = {}
+
+        # XXX necessary?
+        def close(self):
+                self.parent = None
+                self.bar = None
+                self.menus = None
+
+        def addmenu(self, title, after = 0, id=None):
+                if id == None:
+                        id = self.getnextid()
+                if DEBUG: print 'Newmenu', title, id # XXXX
+                m = NewMenu(id, title)
+                m.InsertMenu(after)
+                if after >= 0:
+                        if self.parent:
+                                self.parent.needmenubarredraw = 1
+                        else:
+                                DrawMenuBar()
+                return id, m
+
+        def delmenu(self, id):
+                if DEBUG: print 'Delmenu', id # XXXX
+                DeleteMenu(id)
+
+        def addpopup(self, title = ''):
+                return self.addmenu(title, -1)
+
+# Useless:
+#       def install(self):
+#               if not self.bar: return
+#               SetMenuBar(self.bar)
+#               if self.parent:
+#                       self.parent.needmenubarredraw = 1
+#               else:
+#                       DrawMenuBar()
+
+        def fixmenudimstate(self):
+                for m in self.menus.keys():
+                        menu = self.menus[m]
+                        if menu.__class__ == FrameWork.AppleMenu:
+                                continue
+                        for i in range(len(menu.items)):
+                                label, shortcut, callback, kind = menu.items[i]
+                                if type(callback) == types.StringType:
+                                        wid = MyFrontWindow()
+                                        if wid and self.parent._windows.has_key(wid):
+                                                window = self.parent._windows[wid]
+                                                if hasattr(window, "domenu_" + callback):
+                                                        menu.menu.EnableMenuItem(i + 1)
+                                                elif hasattr(self.parent, "domenu_" + callback):
+                                                        menu.menu.EnableMenuItem(i + 1)
+                                                else:
+                                                        menu.menu.DisableMenuItem(i + 1)
+                                        elif hasattr(self.parent, "domenu_" + callback):
+                                                menu.menu.EnableMenuItem(i + 1)
+                                        else:
+                                                menu.menu.DisableMenuItem(i + 1)
+                                elif callback:
+                                        pass
+
+        def dispatch(self, id, item, window, event):
+                if self.menus.has_key(id):
+                        self.menus[id].dispatch(id, item, window, event)
+                else:
+                        if DEBUG: print "MenuBar.dispatch(%d, %d, %s, %s)" % \
+                                (id, item, window, event)
+
 
 # XXX Need a way to get menus as resources and bind them to callbacks
 
 class Menu:
-	"One menu."
-	
-	def __init__(self, bar, title, after=0, id=None):
-		self.bar = bar
-		self.id, self.menu = self.bar.addmenu(title, after, id)
-		bar.menus[self.id] = self
-		self.items = []
-		self._parent = None
-		
-	def delete(self):
-		self.bar.delmenu(self.id)
-		del self.bar.menus[self.id]
-		self.menu.DisposeMenu()
-		del self.bar
-		del self.items
-		del self.menu
-		del self.id
-		del self._parent
-		
-	def additem(self, label, shortcut=None, callback=None, kind=None):
-		self.menu.AppendMenu('x')		# add a dummy string
-		self.items.append((label, shortcut, callback, kind))
-		item = len(self.items)
-		if isinstance(label, unicode):
-			self.menu.SetMenuItemTextWithCFString(item, label)
-		else:
-			self.menu.SetMenuItemText(item, label)
-		if shortcut and type(shortcut) == type(()):
-			modifiers, char = shortcut[:2]
-			self.menu.SetItemCmd(item, ord(char))
-			self.menu.SetMenuItemModifiers(item, modifiers)
-			if len(shortcut) > 2:
-				self.menu.SetMenuItemKeyGlyph(item, shortcut[2])
-		elif shortcut:	
-			self.menu.SetItemCmd(item, ord(shortcut))
-		return item
-		
-	def delitem(self, item):
-		if item != len(self.items):
-			raise 'Can only delete last item of a menu'
-		self.menu.DeleteMenuItem(item)
-		del self.items[item-1]
-	
-	def addcheck(self, label, shortcut=None, callback=None):
-		return self.additem(label, shortcut, callback, 'check')
-	
-	def addradio(self, label, shortcut=None, callback=None):
-		return self.additem(label, shortcut, callback, 'radio')
-	
-	def addseparator(self):
-		self.menu.AppendMenu('(-')
-		self.items.append(('', None, None, 'separator'))
-	
-	def addsubmenu(self, label, title=''):
-		sub = Menu(self.bar, title, -1)
-		item = self.additem(label, '\x1B', None, 'submenu')
-		self.menu.SetItemMark(item, sub.id)
-		sub._parent = self
-		sub._parent_item = item
-		return sub
-	
-	def dispatch(self, id, item, window, event):
-		title, shortcut, callback, mtype = self.items[item-1]
-		if callback:
-			if not self.bar.parent or type(callback) <> types.StringType:
-				menuhandler = callback
-			else: 
-				# callback is string
-				wid = MyFrontWindow()
-				if wid and self.bar.parent._windows.has_key(wid):
-					window = self.bar.parent._windows[wid]
-					if hasattr(window, "domenu_" + callback):
-						menuhandler = getattr(window, "domenu_" + callback)
-					elif hasattr(self.bar.parent, "domenu_" + callback):
-						menuhandler = getattr(self.bar.parent, "domenu_" + callback)
-					else:
-						# nothing we can do. we shouldn't have come this far
-						# since the menu item should have been disabled...
-						return
-				elif hasattr(self.bar.parent, "domenu_" + callback):
-					menuhandler = getattr(self.bar.parent, "domenu_" + callback)
-				else:
-					# nothing we can do. we shouldn't have come this far
-					# since the menu item should have been disabled...
-					return
-			menuhandler(id, item, window, event)
+        "One menu."
 
-	def enable(self, onoff):
-		if onoff:
-			self.menu.EnableMenuItem(0)
-			if self._parent:
-				self._parent.menu.EnableMenuItem(self._parent_item)
-		else:
-			self.menu.DisableMenuItem(0)
-			if self._parent:
-				self._parent.menu.DisableMenuItem(self._parent_item)
-		if self.bar and self.bar.parent:
-				self.bar.parent.needmenubarredraw = 1
-			
+        def __init__(self, bar, title, after=0, id=None):
+                self.bar = bar
+                self.id, self.menu = self.bar.addmenu(title, after, id)
+                bar.menus[self.id] = self
+                self.items = []
+                self._parent = None
+
+        def delete(self):
+                self.bar.delmenu(self.id)
+                del self.bar.menus[self.id]
+                self.menu.DisposeMenu()
+                del self.bar
+                del self.items
+                del self.menu
+                del self.id
+                del self._parent
+
+        def additem(self, label, shortcut=None, callback=None, kind=None):
+                self.menu.AppendMenu('x')               # add a dummy string
+                self.items.append((label, shortcut, callback, kind))
+                item = len(self.items)
+                if isinstance(label, unicode):
+                        self.menu.SetMenuItemTextWithCFString(item, label)
+                else:
+                        self.menu.SetMenuItemText(item, label)
+                if shortcut and type(shortcut) == type(()):
+                        modifiers, char = shortcut[:2]
+                        self.menu.SetItemCmd(item, ord(char))
+                        self.menu.SetMenuItemModifiers(item, modifiers)
+                        if len(shortcut) > 2:
+                                self.menu.SetMenuItemKeyGlyph(item, shortcut[2])
+                elif shortcut:
+                        self.menu.SetItemCmd(item, ord(shortcut))
+                return item
+
+        def delitem(self, item):
+                if item != len(self.items):
+                        raise 'Can only delete last item of a menu'
+                self.menu.DeleteMenuItem(item)
+                del self.items[item-1]
+
+        def addcheck(self, label, shortcut=None, callback=None):
+                return self.additem(label, shortcut, callback, 'check')
+
+        def addradio(self, label, shortcut=None, callback=None):
+                return self.additem(label, shortcut, callback, 'radio')
+
+        def addseparator(self):
+                self.menu.AppendMenu('(-')
+                self.items.append(('', None, None, 'separator'))
+
+        def addsubmenu(self, label, title=''):
+                sub = Menu(self.bar, title, -1)
+                item = self.additem(label, '\x1B', None, 'submenu')
+                self.menu.SetItemMark(item, sub.id)
+                sub._parent = self
+                sub._parent_item = item
+                return sub
+
+        def dispatch(self, id, item, window, event):
+                title, shortcut, callback, mtype = self.items[item-1]
+                if callback:
+                        if not self.bar.parent or type(callback) <> types.StringType:
+                                menuhandler = callback
+                        else:
+                                # callback is string
+                                wid = MyFrontWindow()
+                                if wid and self.bar.parent._windows.has_key(wid):
+                                        window = self.bar.parent._windows[wid]
+                                        if hasattr(window, "domenu_" + callback):
+                                                menuhandler = getattr(window, "domenu_" + callback)
+                                        elif hasattr(self.bar.parent, "domenu_" + callback):
+                                                menuhandler = getattr(self.bar.parent, "domenu_" + callback)
+                                        else:
+                                                # nothing we can do. we shouldn't have come this far
+                                                # since the menu item should have been disabled...
+                                                return
+                                elif hasattr(self.bar.parent, "domenu_" + callback):
+                                        menuhandler = getattr(self.bar.parent, "domenu_" + callback)
+                                else:
+                                        # nothing we can do. we shouldn't have come this far
+                                        # since the menu item should have been disabled...
+                                        return
+                        menuhandler(id, item, window, event)
+
+        def enable(self, onoff):
+                if onoff:
+                        self.menu.EnableMenuItem(0)
+                        if self._parent:
+                                self._parent.menu.EnableMenuItem(self._parent_item)
+                else:
+                        self.menu.DisableMenuItem(0)
+                        if self._parent:
+                                self._parent.menu.DisableMenuItem(self._parent_item)
+                if self.bar and self.bar.parent:
+                                self.bar.parent.needmenubarredraw = 1
+
 class PopupMenu(Menu):
-	def __init__(self, bar):
-		Menu.__init__(self, bar, '(popup)', -1)
-		
-	def popup(self, x, y, event, default=1, window=None):
-		# NOTE that x and y are global coordinates, and they should probably
-		# be topleft of the button the user clicked (not mouse-coordinates),
-		# so the popup nicely overlaps.
-		reply = self.menu.PopUpMenuSelect(x, y, default)
-		if not reply:
-			return
-		id = (reply >> 16) & 0xffff
-		item = reply & 0xffff
-		if not window:
-			wid = MyFrontWindow()
-			try:
-				window = self.bar.parent._windows[wid]
-			except:
-				pass # If we can't find the window we pass None
-		self.dispatch(id, item, window, event)
+        def __init__(self, bar):
+                Menu.__init__(self, bar, '(popup)', -1)
+
+        def popup(self, x, y, event, default=1, window=None):
+                # NOTE that x and y are global coordinates, and they should probably
+                # be topleft of the button the user clicked (not mouse-coordinates),
+                # so the popup nicely overlaps.
+                reply = self.menu.PopUpMenuSelect(x, y, default)
+                if not reply:
+                        return
+                id = (reply >> 16) & 0xffff
+                item = reply & 0xffff
+                if not window:
+                        wid = MyFrontWindow()
+                        try:
+                                window = self.bar.parent._windows[wid]
+                        except:
+                                pass # If we can't find the window we pass None
+                self.dispatch(id, item, window, event)
 
 class MenuItem:
-	def __init__(self, menu, title, shortcut=None, callback=None, kind=None):
-		self.item = menu.additem(title, shortcut, callback)
-		self.menu = menu
-		
-	def delete(self):
-		self.menu.delitem(self.item)
-		del self.menu
-		del self.item
-		
-	def check(self, onoff):
-		self.menu.menu.CheckMenuItem(self.item, onoff)
+        def __init__(self, menu, title, shortcut=None, callback=None, kind=None):
+                self.item = menu.additem(title, shortcut, callback)
+                self.menu = menu
 
-	def enable(self, onoff):
-		if onoff:
-			self.menu.menu.EnableMenuItem(self.item)
-		else:
-			self.menu.menu.DisableMenuItem(self.item)
-			
-	def settext(self, text):
-		self.menu.menu.SetMenuItemText(self.item, text)
-		
-	def setstyle(self, style):
-		self.menu.menu.SetItemStyle(self.item, style)
-		
-	def seticon(self, icon):
-		self.menu.menu.SetItemIcon(self.item, icon)
-		
-	def setcmd(self, cmd):
-		self.menu.menu.SetItemCmd(self.item, cmd)
-		
-	def setmark(self, cmd):
-		self.menu.menu.SetItemMark(self.item, cmd)
-		
+        def delete(self):
+                self.menu.delitem(self.item)
+                del self.menu
+                del self.item
+
+        def check(self, onoff):
+                self.menu.menu.CheckMenuItem(self.item, onoff)
+
+        def enable(self, onoff):
+                if onoff:
+                        self.menu.menu.EnableMenuItem(self.item)
+                else:
+                        self.menu.menu.DisableMenuItem(self.item)
+
+        def settext(self, text):
+                self.menu.menu.SetMenuItemText(self.item, text)
+
+        def setstyle(self, style):
+                self.menu.menu.SetItemStyle(self.item, style)
+
+        def seticon(self, icon):
+                self.menu.menu.SetItemIcon(self.item, icon)
+
+        def setcmd(self, cmd):
+                self.menu.menu.SetItemCmd(self.item, cmd)
+
+        def setmark(self, cmd):
+                self.menu.menu.SetItemMark(self.item, cmd)
+
 
 class RadioItem(MenuItem):
-	def __init__(self, menu, title, shortcut=None, callback=None):
-		MenuItem.__init__(self, menu, title, shortcut, callback, 'radio')
+        def __init__(self, menu, title, shortcut=None, callback=None):
+                MenuItem.__init__(self, menu, title, shortcut, callback, 'radio')
 
 class CheckItem(MenuItem):
-	def __init__(self, menu, title, shortcut=None, callback=None):
-		MenuItem.__init__(self, menu, title, shortcut, callback, 'check')
+        def __init__(self, menu, title, shortcut=None, callback=None):
+                MenuItem.__init__(self, menu, title, shortcut, callback, 'check')
 
 def Separator(menu):
-	menu.addseparator()
+        menu.addseparator()
 
 def SubMenu(menu, label, title=''):
-	return menu.addsubmenu(label, title)
+        return menu.addsubmenu(label, title)
 
 
 class AppleMenu(Menu):
-	
-	def __init__(self, bar, abouttext="About me...", aboutcallback=None):
-		Menu.__init__(self, bar, "\024", id=SIOUX_APPLEMENU_ID)
-		if MacOS.runtimemodel == 'ppc':
-			self.additem(abouttext, None, aboutcallback)
-			self.addseparator()
-			self.menu.AppendResMenu('DRVR')
-		else:
-			# Additem()'s tricks do not work for "apple" menu under Carbon
-			self.menu.InsertMenuItem(abouttext, 0)
-			self.items.append((abouttext, None, aboutcallback, None))
-	
-	def dispatch(self, id, item, window, event):
-		if item == 1:
-			Menu.dispatch(self, id, item, window, event)
-		elif MacOS.runtimemodel == 'ppc':
-			name = self.menu.GetMenuItemText(item)
-			OpenDeskAcc(name)
-			
+
+        def __init__(self, bar, abouttext="About me...", aboutcallback=None):
+                Menu.__init__(self, bar, "\024", id=SIOUX_APPLEMENU_ID)
+                if MacOS.runtimemodel == 'ppc':
+                        self.additem(abouttext, None, aboutcallback)
+                        self.addseparator()
+                        self.menu.AppendResMenu('DRVR')
+                else:
+                        # Additem()'s tricks do not work for "apple" menu under Carbon
+                        self.menu.InsertMenuItem(abouttext, 0)
+                        self.items.append((abouttext, None, aboutcallback, None))
+
+        def dispatch(self, id, item, window, event):
+                if item == 1:
+                        Menu.dispatch(self, id, item, window, event)
+                elif MacOS.runtimemodel == 'ppc':
+                        name = self.menu.GetMenuItemText(item)
+                        OpenDeskAcc(name)
+
 class HelpMenu(Menu):
-	def __init__(self, bar):
-		# Note we don't call Menu.__init__, we do the necessary things by hand
-		self.bar = bar
-		self.menu, index = HMGetHelpMenu()
-		self.id = self.menu.GetMenuID()
-		bar.menus[self.id] = self
-		# The next line caters for the entries the system already handles for us
-		self.items = [None]*(index-1)
-		self._parent = None
-		
+        def __init__(self, bar):
+                # Note we don't call Menu.__init__, we do the necessary things by hand
+                self.bar = bar
+                self.menu, index = HMGetHelpMenu()
+                self.id = self.menu.GetMenuID()
+                bar.menus[self.id] = self
+                # The next line caters for the entries the system already handles for us
+                self.items = [None]*(index-1)
+                self._parent = None
+
 
 class Window:
-	"""A single window belonging to an application"""
-	
-	def __init__(self, parent):
-		self.wid = None
-		self.parent = parent
-		
-	def open(self, bounds=(40, 40, 400, 400), resid=None):
-		if resid <> None:
-			self.wid = GetNewWindow(resid, -1)
-		else:
-			self.wid = NewWindow(bounds, self.__class__.__name__, 1,
-				8, -1, 1, 0)	# changed to proc id 8 to include zoom box. jvr
-		self.do_postopen()
-		
-	def do_postopen(self):
-		"""Tell our parent we exist"""
-		self.parent.appendwindow(self.wid, self)
-		
-	def close(self):
-		self.do_postclose()
-			
-	def do_postclose(self):
-		self.parent.removewindow(self.wid)
-		self.parent = None
-		self.wid = None
-		
-	def SetPort(self):
-		# Convinience method
-		SetPort(self.wid)
-		
-	def GetWindow(self):
-		return self.wid
-	
-	def do_inDrag(self, partcode, window, event):
-		where = event[3]
-		window.DragWindow(where, self.draglimit)
-	
-	draglimit = screenbounds
-	
-	def do_inGoAway(self, partcode, window, event):
-		where = event[3]
-		if window.TrackGoAway(where):
-			self.close()
-	
-	def do_inZoom(self, partcode, window, event):
-		(what, message, when, where, modifiers) = event
-		if window.TrackBox(where, partcode):
-			window.ZoomWindow(partcode, 1)
-			rect = window.GetWindowUserState()				# so that zoom really works... jvr
-			self.do_postresize(rect[2] - rect[0], rect[3] - rect[1], window)	# jvr
-	
-	def do_inZoomIn(self, partcode, window, event):
-		SetPort(window) # !!!
-		self.do_inZoom(partcode, window, event)
-	
-	def do_inZoomOut(self, partcode, window, event):
-		SetPort(window) # !!!
-		self.do_inZoom(partcode, window, event)
-	
-	def do_inGrow(self, partcode, window, event):
-		(what, message, when, where, modifiers) = event
-		result = window.GrowWindow(where, self.growlimit)
-		if result:
-			height = (result>>16) & 0xffff	# Hi word
-			width = result & 0xffff		# Lo word
-			self.do_resize(width, height, window)
-	
-	growlimit = (50, 50, screenbounds[2] - screenbounds[0], screenbounds[3] - screenbounds[1])	# jvr
-	
-	def do_resize(self, width, height, window):
-		l, t, r, b = self.wid.GetWindowPort().GetPortBounds()			# jvr, forGrowIcon
-		self.SetPort()							# jvr
-		self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))	# jvr
-		window.SizeWindow(width, height, 1)		# changed updateFlag to true jvr
-		self.do_postresize(width, height, window)
-	
-	def do_postresize(self, width, height, window):
-		SetPort(window)
-		self.wid.InvalWindowRect(window.GetWindowPort().GetPortBounds())
-	
-	def do_inContent(self, partcode, window, event):
-		#
-		# If we're not frontmost, select ourselves and wait for
-		# the activate event.
-		#
-		if MyFrontWindow() <> window:
-			window.SelectWindow()
-			return
-		# We are. Handle the event.
-		(what, message, when, where, modifiers) = event
-		SetPort(window)
-		local = GlobalToLocal(where)
-		self.do_contentclick(local, modifiers, event)
-		
-	def do_contentclick(self, local, modifiers, event):
-		if DEBUG:
-			print 'Click in contents at %s, modifiers %s'%(local, modifiers)
-	
-	def do_rawupdate(self, window, event):
-		if DEBUG: print "raw update for", window
-		SetPort(window)
-		window.BeginUpdate()
-		self.do_update(window, event)
-		window.EndUpdate()
-	
-	def do_update(self, window, event):
-		if DEBUG:
-			import time
-			for i in range(8):
-				time.sleep(0.1)
-				InvertRgn(window.GetWindowPort().visRgn)
-			FillRgn(window.GetWindowPort().visRgn, GetQDGlobalsGray())
-		else:
-			EraseRgn(window.GetWindowPort().visRgn)
-		
-	def do_activate(self, activate, event):
-		if DEBUG: print 'Activate %d for %s'%(activate, self.wid)
-		
+        """A single window belonging to an application"""
+
+        def __init__(self, parent):
+                self.wid = None
+                self.parent = parent
+
+        def open(self, bounds=(40, 40, 400, 400), resid=None):
+                if resid <> None:
+                        self.wid = GetNewWindow(resid, -1)
+                else:
+                        self.wid = NewWindow(bounds, self.__class__.__name__, 1,
+                                8, -1, 1, 0)    # changed to proc id 8 to include zoom box. jvr
+                self.do_postopen()
+
+        def do_postopen(self):
+                """Tell our parent we exist"""
+                self.parent.appendwindow(self.wid, self)
+
+        def close(self):
+                self.do_postclose()
+
+        def do_postclose(self):
+                self.parent.removewindow(self.wid)
+                self.parent = None
+                self.wid = None
+
+        def SetPort(self):
+                # Convinience method
+                SetPort(self.wid)
+
+        def GetWindow(self):
+                return self.wid
+
+        def do_inDrag(self, partcode, window, event):
+                where = event[3]
+                window.DragWindow(where, self.draglimit)
+
+        draglimit = screenbounds
+
+        def do_inGoAway(self, partcode, window, event):
+                where = event[3]
+                if window.TrackGoAway(where):
+                        self.close()
+
+        def do_inZoom(self, partcode, window, event):
+                (what, message, when, where, modifiers) = event
+                if window.TrackBox(where, partcode):
+                        window.ZoomWindow(partcode, 1)
+                        rect = window.GetWindowUserState()                              # so that zoom really works... jvr
+                        self.do_postresize(rect[2] - rect[0], rect[3] - rect[1], window)        # jvr
+
+        def do_inZoomIn(self, partcode, window, event):
+                SetPort(window) # !!!
+                self.do_inZoom(partcode, window, event)
+
+        def do_inZoomOut(self, partcode, window, event):
+                SetPort(window) # !!!
+                self.do_inZoom(partcode, window, event)
+
+        def do_inGrow(self, partcode, window, event):
+                (what, message, when, where, modifiers) = event
+                result = window.GrowWindow(where, self.growlimit)
+                if result:
+                        height = (result>>16) & 0xffff  # Hi word
+                        width = result & 0xffff         # Lo word
+                        self.do_resize(width, height, window)
+
+        growlimit = (50, 50, screenbounds[2] - screenbounds[0], screenbounds[3] - screenbounds[1])      # jvr
+
+        def do_resize(self, width, height, window):
+                l, t, r, b = self.wid.GetWindowPort().GetPortBounds()                   # jvr, forGrowIcon
+                self.SetPort()                                                  # jvr
+                self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))        # jvr
+                window.SizeWindow(width, height, 1)             # changed updateFlag to true jvr
+                self.do_postresize(width, height, window)
+
+        def do_postresize(self, width, height, window):
+                SetPort(window)
+                self.wid.InvalWindowRect(window.GetWindowPort().GetPortBounds())
+
+        def do_inContent(self, partcode, window, event):
+                #
+                # If we're not frontmost, select ourselves and wait for
+                # the activate event.
+                #
+                if MyFrontWindow() <> window:
+                        window.SelectWindow()
+                        return
+                # We are. Handle the event.
+                (what, message, when, where, modifiers) = event
+                SetPort(window)
+                local = GlobalToLocal(where)
+                self.do_contentclick(local, modifiers, event)
+
+        def do_contentclick(self, local, modifiers, event):
+                if DEBUG:
+                        print 'Click in contents at %s, modifiers %s'%(local, modifiers)
+
+        def do_rawupdate(self, window, event):
+                if DEBUG: print "raw update for", window
+                SetPort(window)
+                window.BeginUpdate()
+                self.do_update(window, event)
+                window.EndUpdate()
+
+        def do_update(self, window, event):
+                if DEBUG:
+                        import time
+                        for i in range(8):
+                                time.sleep(0.1)
+                                InvertRgn(window.GetWindowPort().visRgn)
+                        FillRgn(window.GetWindowPort().visRgn, GetQDGlobalsGray())
+                else:
+                        EraseRgn(window.GetWindowPort().visRgn)
+
+        def do_activate(self, activate, event):
+                if DEBUG: print 'Activate %d for %s'%(activate, self.wid)
+
 class ControlsWindow(Window):
 
-	def do_rawupdate(self, window, event):
-		if DEBUG: print "raw update for", window
-		SetPort(window)
-		window.BeginUpdate()
-		self.do_update(window, event)
-		#DrawControls(window)					# jvr
-		UpdateControls(window, window.GetWindowPort().visRgn)	# jvr
-		window.DrawGrowIcon()
-		window.EndUpdate()
-	
-	def do_controlhit(self, window, control, pcode, event):
-		if DEBUG: print "control hit in", window, "on", control, "; pcode =", pcode
+        def do_rawupdate(self, window, event):
+                if DEBUG: print "raw update for", window
+                SetPort(window)
+                window.BeginUpdate()
+                self.do_update(window, event)
+                #DrawControls(window)                                   # jvr
+                UpdateControls(window, window.GetWindowPort().visRgn)   # jvr
+                window.DrawGrowIcon()
+                window.EndUpdate()
 
-	def do_inContent(self, partcode, window, event):
-		if MyFrontWindow() <> window:
-			window.SelectWindow()
-			return
-		(what, message, when, where, modifiers) = event
-		SetPort(window)  # XXXX Needed?
-		local = GlobalToLocal(where)
-		pcode, control = FindControl(local, window)
-		if pcode and control:
-			self.do_rawcontrolhit(window, control, pcode, local, event)
-		else:
-			if DEBUG: print "FindControl(%s, %s) -> (%s, %s)" % \
-				(local, window, pcode, control)
-			self.do_contentclick(local, modifiers, event)
-			
-	def do_rawcontrolhit(self, window, control, pcode, local, event):
-		pcode = control.TrackControl(local)
-		if pcode:
-			self.do_controlhit(window, control, pcode, event)
-			
+        def do_controlhit(self, window, control, pcode, event):
+                if DEBUG: print "control hit in", window, "on", control, "; pcode =", pcode
+
+        def do_inContent(self, partcode, window, event):
+                if MyFrontWindow() <> window:
+                        window.SelectWindow()
+                        return
+                (what, message, when, where, modifiers) = event
+                SetPort(window)  # XXXX Needed?
+                local = GlobalToLocal(where)
+                pcode, control = FindControl(local, window)
+                if pcode and control:
+                        self.do_rawcontrolhit(window, control, pcode, local, event)
+                else:
+                        if DEBUG: print "FindControl(%s, %s) -> (%s, %s)" % \
+                                (local, window, pcode, control)
+                        self.do_contentclick(local, modifiers, event)
+
+        def do_rawcontrolhit(self, window, control, pcode, local, event):
+                pcode = control.TrackControl(local)
+                if pcode:
+                        self.do_controlhit(window, control, pcode, event)
+
 class ScrolledWindow(ControlsWindow):
-	def __init__(self, parent):
-		self.barx = self.bary = None
-		self.barx_enabled = self.bary_enabled = 1
-		self.activated = 1
-		ControlsWindow.__init__(self, parent)
+        def __init__(self, parent):
+                self.barx = self.bary = None
+                self.barx_enabled = self.bary_enabled = 1
+                self.activated = 1
+                ControlsWindow.__init__(self, parent)
 
-	def scrollbars(self, wantx=1, wanty=1):
-		SetPort(self.wid)
-		self.barx = self.bary = None
-		self.barx_enabled = self.bary_enabled = 1
-		x0, y0, x1, y1 = self.wid.GetWindowPort().GetPortBounds()
-		vx, vy = self.getscrollbarvalues()
-		if vx == None: self.barx_enabled, vx = 0, 0
-		if vy == None: self.bary_enabled, vy = 0, 0
-		if wantx:
-			rect = x0-1, y1-(SCROLLBARWIDTH-1), x1-(SCROLLBARWIDTH-2), y1+1
-			self.barx = NewControl(self.wid, rect, "", 1, vx, 0, 32767, 16, 0)
-			if not self.barx_enabled: self.barx.HiliteControl(255)
-##			self.wid.InvalWindowRect(rect)
-		if wanty:
-			rect = x1-(SCROLLBARWIDTH-1), y0-1, x1+1, y1-(SCROLLBARWIDTH-2)
-			self.bary = NewControl(self.wid, rect, "", 1, vy, 0, 32767, 16, 0)
-			if not self.bary_enabled: self.bary.HiliteControl(255)
-##			self.wid.InvalWindowRect(rect)
-			
-	def do_postclose(self):
-		self.barx = self.bary = None
-		ControlsWindow.do_postclose(self)
-		
-	def do_activate(self, onoff, event):
-		self.activated = onoff
-		if onoff:
-			if self.barx and self.barx_enabled:
-				self.barx.ShowControl()	# jvr
-			if self.bary and self.bary_enabled:
-				self.bary.ShowControl()	# jvr
-		else:
-			if self.barx:
-				self.barx.HideControl()	# jvr; An inactive window should have *hidden*
-							# scrollbars, not just dimmed (no matter what
-							# BBEdit does... look at the Finder)
-			if self.bary:
-				self.bary.HideControl()	# jvr
-		self.wid.DrawGrowIcon()			# jvr
-			
-	def do_postresize(self, width, height, window):
-		l, t, r, b = self.wid.GetWindowPort().GetPortBounds()
-		self.SetPort()
-		if self.barx:
-			self.barx.HideControl()		# jvr
-			self.barx.MoveControl(l-1, b-(SCROLLBARWIDTH-1))
-			self.barx.SizeControl((r-l)-(SCROLLBARWIDTH-3), SCROLLBARWIDTH)	# jvr
-		if self.bary:
-			self.bary.HideControl()		# jvr
-			self.bary.MoveControl(r-(SCROLLBARWIDTH-1), t-1)
-			self.bary.SizeControl(SCROLLBARWIDTH, (b-t)-(SCROLLBARWIDTH-3))	# jvr
-		if self.barx:
-			self.barx.ShowControl()		# jvr
-			self.wid.ValidWindowRect((l, b - SCROLLBARWIDTH + 1, r - SCROLLBARWIDTH + 2, b))	# jvr
-		if self.bary:
-			self.bary.ShowControl()		# jvr
-			self.wid.ValidWindowRect((r - SCROLLBARWIDTH + 1, t, r, b - SCROLLBARWIDTH + 2))	# jvr
-		self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))	# jvr, growicon
+        def scrollbars(self, wantx=1, wanty=1):
+                SetPort(self.wid)
+                self.barx = self.bary = None
+                self.barx_enabled = self.bary_enabled = 1
+                x0, y0, x1, y1 = self.wid.GetWindowPort().GetPortBounds()
+                vx, vy = self.getscrollbarvalues()
+                if vx == None: self.barx_enabled, vx = 0, 0
+                if vy == None: self.bary_enabled, vy = 0, 0
+                if wantx:
+                        rect = x0-1, y1-(SCROLLBARWIDTH-1), x1-(SCROLLBARWIDTH-2), y1+1
+                        self.barx = NewControl(self.wid, rect, "", 1, vx, 0, 32767, 16, 0)
+                        if not self.barx_enabled: self.barx.HiliteControl(255)
+##                      self.wid.InvalWindowRect(rect)
+                if wanty:
+                        rect = x1-(SCROLLBARWIDTH-1), y0-1, x1+1, y1-(SCROLLBARWIDTH-2)
+                        self.bary = NewControl(self.wid, rect, "", 1, vy, 0, 32767, 16, 0)
+                        if not self.bary_enabled: self.bary.HiliteControl(255)
+##                      self.wid.InvalWindowRect(rect)
 
-			
-	def do_rawcontrolhit(self, window, control, pcode, local, event):
-		if control == self.barx:
-			which = 'x'
-		elif control == self.bary:
-			which = 'y'
-		else:
-			return 0
-		if pcode in (inUpButton, inDownButton, inPageUp, inPageDown):
-			# We do the work for the buttons and grey area in the tracker
-			dummy = control.TrackControl(local, self.do_controltrack)
-		else:
-			# but the thumb is handled here
-			pcode = control.TrackControl(local)
-			if pcode == inThumb:
-				value = control.GetControlValue()
-				print 'setbars', which, value #DBG
-				self.scrollbar_callback(which, 'set', value)
-				self.updatescrollbars()
-			else:
-				print 'funny part', pcode #DBG
-		return 1
-		
-	def do_controltrack(self, control, pcode):
-		if control == self.barx:
-			which = 'x'
-		elif control == self.bary:
-			which = 'y'
-		else:
-			return
+        def do_postclose(self):
+                self.barx = self.bary = None
+                ControlsWindow.do_postclose(self)
 
-		if pcode == inUpButton:
-			what = '-'
-		elif pcode == inDownButton:
-			what = '+'
-		elif pcode == inPageUp:
-			what = '--'
-		elif pcode == inPageDown:
-			what = '++'
-		else:
-			return
-		self.scrollbar_callback(which, what, None)
-		self.updatescrollbars()
-		
-	def updatescrollbars(self):
-		SetPort(self.wid)
-		vx, vy = self.getscrollbarvalues()
-		if self.barx:
-			if vx == None:
-				self.barx.HiliteControl(255)
-				self.barx_enabled = 0
-			else:
-				if not self.barx_enabled:
-					self.barx_enabled = 1
-					if self.activated:
-						self.barx.HiliteControl(0)
-				self.barx.SetControlValue(vx)
-		if self.bary:
-			if vy == None:
-				self.bary.HiliteControl(255)
-				self.bary_enabled = 0
-			else:
-				if not self.bary_enabled:
-					self.bary_enabled = 1
-					if self.activated:
-						self.bary.HiliteControl(0)
-				self.bary.SetControlValue(vy)
-			
-	# Auxiliary function: convert standard text/image/etc coordinate
-	# to something palatable as getscrollbarvalues() return
-	def scalebarvalue(self, absmin, absmax, curmin, curmax):
-		if curmin <= absmin and curmax >= absmax:
-			return None
-		if curmin <= absmin:
-			return 0
-		if curmax >= absmax:
-			return 32767
-		perc = float(curmin-absmin)/float(absmax-absmin)
-		return int(perc*32767)
-			
-	# To be overridden:
-	
-	def getscrollbarvalues(self):
-		return 0, 0
-		
-	def scrollbar_callback(self, which, what, value):
-		print 'scroll', which, what, value
-	
+        def do_activate(self, onoff, event):
+                self.activated = onoff
+                if onoff:
+                        if self.barx and self.barx_enabled:
+                                self.barx.ShowControl() # jvr
+                        if self.bary and self.bary_enabled:
+                                self.bary.ShowControl() # jvr
+                else:
+                        if self.barx:
+                                self.barx.HideControl() # jvr; An inactive window should have *hidden*
+                                                        # scrollbars, not just dimmed (no matter what
+                                                        # BBEdit does... look at the Finder)
+                        if self.bary:
+                                self.bary.HideControl() # jvr
+                self.wid.DrawGrowIcon()                 # jvr
+
+        def do_postresize(self, width, height, window):
+                l, t, r, b = self.wid.GetWindowPort().GetPortBounds()
+                self.SetPort()
+                if self.barx:
+                        self.barx.HideControl()         # jvr
+                        self.barx.MoveControl(l-1, b-(SCROLLBARWIDTH-1))
+                        self.barx.SizeControl((r-l)-(SCROLLBARWIDTH-3), SCROLLBARWIDTH) # jvr
+                if self.bary:
+                        self.bary.HideControl()         # jvr
+                        self.bary.MoveControl(r-(SCROLLBARWIDTH-1), t-1)
+                        self.bary.SizeControl(SCROLLBARWIDTH, (b-t)-(SCROLLBARWIDTH-3)) # jvr
+                if self.barx:
+                        self.barx.ShowControl()         # jvr
+                        self.wid.ValidWindowRect((l, b - SCROLLBARWIDTH + 1, r - SCROLLBARWIDTH + 2, b))        # jvr
+                if self.bary:
+                        self.bary.ShowControl()         # jvr
+                        self.wid.ValidWindowRect((r - SCROLLBARWIDTH + 1, t, r, b - SCROLLBARWIDTH + 2))        # jvr
+                self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))        # jvr, growicon
+
+
+        def do_rawcontrolhit(self, window, control, pcode, local, event):
+                if control == self.barx:
+                        which = 'x'
+                elif control == self.bary:
+                        which = 'y'
+                else:
+                        return 0
+                if pcode in (inUpButton, inDownButton, inPageUp, inPageDown):
+                        # We do the work for the buttons and grey area in the tracker
+                        dummy = control.TrackControl(local, self.do_controltrack)
+                else:
+                        # but the thumb is handled here
+                        pcode = control.TrackControl(local)
+                        if pcode == inThumb:
+                                value = control.GetControlValue()
+                                print 'setbars', which, value #DBG
+                                self.scrollbar_callback(which, 'set', value)
+                                self.updatescrollbars()
+                        else:
+                                print 'funny part', pcode #DBG
+                return 1
+
+        def do_controltrack(self, control, pcode):
+                if control == self.barx:
+                        which = 'x'
+                elif control == self.bary:
+                        which = 'y'
+                else:
+                        return
+
+                if pcode == inUpButton:
+                        what = '-'
+                elif pcode == inDownButton:
+                        what = '+'
+                elif pcode == inPageUp:
+                        what = '--'
+                elif pcode == inPageDown:
+                        what = '++'
+                else:
+                        return
+                self.scrollbar_callback(which, what, None)
+                self.updatescrollbars()
+
+        def updatescrollbars(self):
+                SetPort(self.wid)
+                vx, vy = self.getscrollbarvalues()
+                if self.barx:
+                        if vx == None:
+                                self.barx.HiliteControl(255)
+                                self.barx_enabled = 0
+                        else:
+                                if not self.barx_enabled:
+                                        self.barx_enabled = 1
+                                        if self.activated:
+                                                self.barx.HiliteControl(0)
+                                self.barx.SetControlValue(vx)
+                if self.bary:
+                        if vy == None:
+                                self.bary.HiliteControl(255)
+                                self.bary_enabled = 0
+                        else:
+                                if not self.bary_enabled:
+                                        self.bary_enabled = 1
+                                        if self.activated:
+                                                self.bary.HiliteControl(0)
+                                self.bary.SetControlValue(vy)
+
+        # Auxiliary function: convert standard text/image/etc coordinate
+        # to something palatable as getscrollbarvalues() return
+        def scalebarvalue(self, absmin, absmax, curmin, curmax):
+                if curmin <= absmin and curmax >= absmax:
+                        return None
+                if curmin <= absmin:
+                        return 0
+                if curmax >= absmax:
+                        return 32767
+                perc = float(curmin-absmin)/float(absmax-absmin)
+                return int(perc*32767)
+
+        # To be overridden:
+
+        def getscrollbarvalues(self):
+                return 0, 0
+
+        def scrollbar_callback(self, which, what, value):
+                print 'scroll', which, what, value
+
 class DialogWindow(Window):
-	"""A modeless dialog window"""
-	
-	def open(self, resid):
-		self.dlg = GetNewDialog(resid, -1)
-		self.wid = self.dlg.GetDialogWindow()
-		self.do_postopen()
-		
-	def close(self):
-		self.do_postclose()
-		
-	def do_postclose(self):
-		self.dlg = None
-		Window.do_postclose(self)
-		
-	def do_itemhit(self, item, event):
-		print 'Dialog %s, item %d hit'%(self.dlg, item)
-		
-	def do_rawupdate(self, window, event):
-		pass
+        """A modeless dialog window"""
+
+        def open(self, resid):
+                self.dlg = GetNewDialog(resid, -1)
+                self.wid = self.dlg.GetDialogWindow()
+                self.do_postopen()
+
+        def close(self):
+                self.do_postclose()
+
+        def do_postclose(self):
+                self.dlg = None
+                Window.do_postclose(self)
+
+        def do_itemhit(self, item, event):
+                print 'Dialog %s, item %d hit'%(self.dlg, item)
+
+        def do_rawupdate(self, window, event):
+                pass
 
 def ostypecode(x):
-	"Convert a long int to the 4-character code it really is"
-	s = ''
-	for i in range(4):
-		x, c = divmod(x, 256)
-		s = chr(c) + s
-	return s
+        "Convert a long int to the 4-character code it really is"
+        s = ''
+        for i in range(4):
+                x, c = divmod(x, 256)
+                s = chr(c) + s
+        return s
 
 
 class TestApp(Application):
-	
-	"This class is used by the test() function"
-	
-	def makeusermenus(self):
-		self.filemenu = m = Menu(self.menubar, "File")
-		self.saveitem = MenuItem(m, "Save", "S", self.save)
-		Separator(m)
-		self.optionsmenu = mm = SubMenu(m, "Options")
-		self.opt1 = CheckItem(mm, "Arguments", "A")
-		self.opt2 = CheckItem(mm, "Being hit on the head lessons", (kMenuOptionModifier, "A"))
-		self.opt3 = CheckItem(mm, "Complaints", (kMenuOptionModifier|kMenuNoCommandModifier, "A"))
-		Separator(m)
-		self.itemeh = MenuItem(m, "Enable Help", None, self.enablehelp)
-		self.itemdbg = MenuItem(m, "Debug", None, self.debug)
-		Separator(m)
-		self.quititem = MenuItem(m, "Quit", "Q", self.quit)
-	
-	def save(self, *args):
-		print "Save"
-	
-	def quit(self, *args):
-		raise self
-		
-	def enablehelp(self, *args):
-		hm = self.gethelpmenu()
-		self.nohelpitem = MenuItem(hm, "There isn't any", None, self.nohelp)
-		
-	def nohelp(self, *args):
-		print "I told you there isn't any!"
-		
-	def debug(self, *args):
-		import pdb
-		pdb.set_trace()
+
+        "This class is used by the test() function"
+
+        def makeusermenus(self):
+                self.filemenu = m = Menu(self.menubar, "File")
+                self.saveitem = MenuItem(m, "Save", "S", self.save)
+                Separator(m)
+                self.optionsmenu = mm = SubMenu(m, "Options")
+                self.opt1 = CheckItem(mm, "Arguments", "A")
+                self.opt2 = CheckItem(mm, "Being hit on the head lessons", (kMenuOptionModifier, "A"))
+                self.opt3 = CheckItem(mm, "Complaints", (kMenuOptionModifier|kMenuNoCommandModifier, "A"))
+                Separator(m)
+                self.itemeh = MenuItem(m, "Enable Help", None, self.enablehelp)
+                self.itemdbg = MenuItem(m, "Debug", None, self.debug)
+                Separator(m)
+                self.quititem = MenuItem(m, "Quit", "Q", self.quit)
+
+        def save(self, *args):
+                print "Save"
+
+        def quit(self, *args):
+                raise self
+
+        def enablehelp(self, *args):
+                hm = self.gethelpmenu()
+                self.nohelpitem = MenuItem(hm, "There isn't any", None, self.nohelp)
+
+        def nohelp(self, *args):
+                print "I told you there isn't any!"
+
+        def debug(self, *args):
+                import pdb
+                pdb.set_trace()
 
 
 def test():
-	"Test program"
-	app = TestApp()
-	app.mainloop()
+        "Test program"
+        app = TestApp()
+        app.mainloop()
 
 
 if __name__ == '__main__':
-	test()
+        test()
diff --git a/Lib/plat-mac/MiniAEFrame.py b/Lib/plat-mac/MiniAEFrame.py
index ab54039..a44e6ae 100644
--- a/Lib/plat-mac/MiniAEFrame.py
+++ b/Lib/plat-mac/MiniAEFrame.py
@@ -1,9 +1,9 @@
 """MiniAEFrame - A minimal AppleEvent Application framework.
 
 There are two classes:
-	AEServer -- a mixin class offering nice AE handling.
-	MiniApplication -- a very minimal alternative to FrameWork.py,
-		only suitable for the simplest of AppleEvent servers.
+        AEServer -- a mixin class offering nice AE handling.
+        MiniApplication -- a very minimal alternative to FrameWork.py,
+                only suitable for the simplest of AppleEvent servers.
 """
 
 import sys
@@ -21,179 +21,179 @@
 import aetools
 import EasyDialogs
 
-kHighLevelEvent = 23				# Not defined anywhere for Python yet?
+kHighLevelEvent = 23                            # Not defined anywhere for Python yet?
 
 
 class MiniApplication:
-	
-	"""A minimal FrameWork.Application-like class"""
-	
-	def __init__(self):
-		self.quitting = 0
-		# Initialize menu
-		self.appleid = 1
-		self.quitid = 2
-		Menu.ClearMenuBar()
-		self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024")
-		applemenu.AppendMenu("%s;(-" % self.getaboutmenutext())
-		if MacOS.runtimemodel == 'ppc':
-			applemenu.AppendResMenu('DRVR')
-		applemenu.InsertMenu(0)
-		self.quitmenu = Menu.NewMenu(self.quitid, "File")
-		self.quitmenu.AppendMenu("Quit")
-		self.quitmenu.SetItemCmd(1, ord("Q"))
-		self.quitmenu.InsertMenu(0)
-		Menu.DrawMenuBar()
-	
-	def __del__(self):
-		self.close()
-	
-	def close(self):
-		pass
-	
-	def mainloop(self, mask = everyEvent, timeout = 60*60):
-		while not self.quitting:
-			self.dooneevent(mask, timeout)
-	
-	def _quit(self):
-		self.quitting = 1
-	
-	def dooneevent(self, mask = everyEvent, timeout = 60*60):
-			got, event = Evt.WaitNextEvent(mask, timeout)
-			if got:
-				self.lowlevelhandler(event)
-	
-	def lowlevelhandler(self, event):
-		what, message, when, where, modifiers = event
-		h, v = where
-		if what == kHighLevelEvent:
-			msg = "High Level Event: %s %s" % \
-				(`code(message)`, `code(h | (v<<16))`)
-			try:
-				AE.AEProcessAppleEvent(event)
-			except AE.Error, err:
-				print 'AE error: ', err
-				print 'in', msg
-				traceback.print_exc()
-			return
-		elif what == keyDown:
-			c = chr(message & charCodeMask)
-			if modifiers & cmdKey:
-				if c == '.':
-					raise KeyboardInterrupt, "Command-period"
-				if c == 'q':
-					if hasattr(MacOS, 'OutputSeen'):
-						MacOS.OutputSeen()
-					self.quitting = 1
-					return
-		elif what == mouseDown:
-			partcode, window = Win.FindWindow(where)
-			if partcode == inMenuBar:
-				result = Menu.MenuSelect(where)
-				id = (result>>16) & 0xffff	# Hi word
-				item = result & 0xffff		# Lo word
-				if id == self.appleid:
-					if item == 1:
-						EasyDialogs.Message(self.getabouttext())
-					elif item > 1 and hasattr(Menu, 'OpenDeskAcc'):
-						name = self.applemenu.GetMenuItemText(item)
-						Menu.OpenDeskAcc(name)
-				elif id == self.quitid and item == 1:
-					if hasattr(MacOS, 'OutputSeen'):
-						MacOS.OutputSeen()
-					self.quitting = 1
-				Menu.HiliteMenu(0)
-				return
-		# Anything not handled is passed to Python/SIOUX
-		if hasattr(MacOS, 'HandleEvent'):
-			MacOS.HandleEvent(event)
-		else:
-			print "Unhandled event:", event
-	
-	def getabouttext(self):
-		return self.__class__.__name__
-	
-	def getaboutmenutext(self):
-		return "About %s\311" % self.__class__.__name__
+
+        """A minimal FrameWork.Application-like class"""
+
+        def __init__(self):
+                self.quitting = 0
+                # Initialize menu
+                self.appleid = 1
+                self.quitid = 2
+                Menu.ClearMenuBar()
+                self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024")
+                applemenu.AppendMenu("%s;(-" % self.getaboutmenutext())
+                if MacOS.runtimemodel == 'ppc':
+                        applemenu.AppendResMenu('DRVR')
+                applemenu.InsertMenu(0)
+                self.quitmenu = Menu.NewMenu(self.quitid, "File")
+                self.quitmenu.AppendMenu("Quit")
+                self.quitmenu.SetItemCmd(1, ord("Q"))
+                self.quitmenu.InsertMenu(0)
+                Menu.DrawMenuBar()
+
+        def __del__(self):
+                self.close()
+
+        def close(self):
+                pass
+
+        def mainloop(self, mask = everyEvent, timeout = 60*60):
+                while not self.quitting:
+                        self.dooneevent(mask, timeout)
+
+        def _quit(self):
+                self.quitting = 1
+
+        def dooneevent(self, mask = everyEvent, timeout = 60*60):
+                        got, event = Evt.WaitNextEvent(mask, timeout)
+                        if got:
+                                self.lowlevelhandler(event)
+
+        def lowlevelhandler(self, event):
+                what, message, when, where, modifiers = event
+                h, v = where
+                if what == kHighLevelEvent:
+                        msg = "High Level Event: %s %s" % \
+                                (`code(message)`, `code(h | (v<<16))`)
+                        try:
+                                AE.AEProcessAppleEvent(event)
+                        except AE.Error, err:
+                                print 'AE error: ', err
+                                print 'in', msg
+                                traceback.print_exc()
+                        return
+                elif what == keyDown:
+                        c = chr(message & charCodeMask)
+                        if modifiers & cmdKey:
+                                if c == '.':
+                                        raise KeyboardInterrupt, "Command-period"
+                                if c == 'q':
+                                        if hasattr(MacOS, 'OutputSeen'):
+                                                MacOS.OutputSeen()
+                                        self.quitting = 1
+                                        return
+                elif what == mouseDown:
+                        partcode, window = Win.FindWindow(where)
+                        if partcode == inMenuBar:
+                                result = Menu.MenuSelect(where)
+                                id = (result>>16) & 0xffff      # Hi word
+                                item = result & 0xffff          # Lo word
+                                if id == self.appleid:
+                                        if item == 1:
+                                                EasyDialogs.Message(self.getabouttext())
+                                        elif item > 1 and hasattr(Menu, 'OpenDeskAcc'):
+                                                name = self.applemenu.GetMenuItemText(item)
+                                                Menu.OpenDeskAcc(name)
+                                elif id == self.quitid and item == 1:
+                                        if hasattr(MacOS, 'OutputSeen'):
+                                                MacOS.OutputSeen()
+                                        self.quitting = 1
+                                Menu.HiliteMenu(0)
+                                return
+                # Anything not handled is passed to Python/SIOUX
+                if hasattr(MacOS, 'HandleEvent'):
+                        MacOS.HandleEvent(event)
+                else:
+                        print "Unhandled event:", event
+
+        def getabouttext(self):
+                return self.__class__.__name__
+
+        def getaboutmenutext(self):
+                return "About %s\311" % self.__class__.__name__
 
 
 class AEServer:
-	
-	def __init__(self):
-		self.ae_handlers = {}
-	
-	def installaehandler(self, classe, type, callback):
-		AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
-		self.ae_handlers[(classe, type)] = callback
-	
-	def close(self):
-		for classe, type in self.ae_handlers.keys():
-			AE.AERemoveEventHandler(classe, type)
-	
-	def callback_wrapper(self, _request, _reply):
-		_parameters, _attributes = aetools.unpackevent(_request)
-		_class = _attributes['evcl'].type
-		_type = _attributes['evid'].type
-		
-		if self.ae_handlers.has_key((_class, _type)):
-			_function = self.ae_handlers[(_class, _type)]
-		elif self.ae_handlers.has_key((_class, '****')):
-			_function = self.ae_handlers[(_class, '****')]
-		elif self.ae_handlers.has_key(('****', '****')):
-			_function = self.ae_handlers[('****', '****')]
-		else:
-			raise 'Cannot happen: AE callback without handler', (_class, _type)
-		
-		# XXXX Do key-to-name mapping here
-		
-		_parameters['_attributes'] = _attributes
-		_parameters['_class'] = _class
-		_parameters['_type'] = _type
-		if _parameters.has_key('----'):
-			_object = _parameters['----']
-			del _parameters['----']
-			# The try/except that used to be here can mask programmer errors.
-			# Let the program crash, the programmer can always add a **args
-			# to the formal parameter list.
-			rv = apply(_function, (_object,), _parameters)
-		else:
-			#Same try/except comment as above
-			rv = apply(_function, (), _parameters)
-		
-		if rv == None:
-			aetools.packevent(_reply, {})
-		else:
-			aetools.packevent(_reply, {'----':rv})
+
+        def __init__(self):
+                self.ae_handlers = {}
+
+        def installaehandler(self, classe, type, callback):
+                AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
+                self.ae_handlers[(classe, type)] = callback
+
+        def close(self):
+                for classe, type in self.ae_handlers.keys():
+                        AE.AERemoveEventHandler(classe, type)
+
+        def callback_wrapper(self, _request, _reply):
+                _parameters, _attributes = aetools.unpackevent(_request)
+                _class = _attributes['evcl'].type
+                _type = _attributes['evid'].type
+
+                if self.ae_handlers.has_key((_class, _type)):
+                        _function = self.ae_handlers[(_class, _type)]
+                elif self.ae_handlers.has_key((_class, '****')):
+                        _function = self.ae_handlers[(_class, '****')]
+                elif self.ae_handlers.has_key(('****', '****')):
+                        _function = self.ae_handlers[('****', '****')]
+                else:
+                        raise 'Cannot happen: AE callback without handler', (_class, _type)
+
+                # XXXX Do key-to-name mapping here
+
+                _parameters['_attributes'] = _attributes
+                _parameters['_class'] = _class
+                _parameters['_type'] = _type
+                if _parameters.has_key('----'):
+                        _object = _parameters['----']
+                        del _parameters['----']
+                        # The try/except that used to be here can mask programmer errors.
+                        # Let the program crash, the programmer can always add a **args
+                        # to the formal parameter list.
+                        rv = _function(_object, **_parameters)
+                else:
+                        #Same try/except comment as above
+                        rv = _function(**_parameters)
+
+                if rv == None:
+                        aetools.packevent(_reply, {})
+                else:
+                        aetools.packevent(_reply, {'----':rv})
 
 
 def code(x):
-	"Convert a long int to the 4-character code it really is"
-	s = ''
-	for i in range(4):
-		x, c = divmod(x, 256)
-		s = chr(c) + s
-	return s
+        "Convert a long int to the 4-character code it really is"
+        s = ''
+        for i in range(4):
+                x, c = divmod(x, 256)
+                s = chr(c) + s
+        return s
 
 class _Test(AEServer, MiniApplication):
-	"""Mini test application, handles required events"""
-	
-	def __init__(self):
-		MiniApplication.__init__(self)
-		AEServer.__init__(self)
-		self.installaehandler('aevt', 'oapp', self.open_app)
-		self.installaehandler('aevt', 'quit', self.quit)
-		self.installaehandler('****', '****', self.other)
-		self.mainloop()
+        """Mini test application, handles required events"""
 
-	def quit(self, **args):
-		self._quit()
-		
-	def open_app(self, **args):
-		pass
-		
-	def other(self, _object=None, _class=None, _type=None, **args):
-		print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
-		
+        def __init__(self):
+                MiniApplication.__init__(self)
+                AEServer.__init__(self)
+                self.installaehandler('aevt', 'oapp', self.open_app)
+                self.installaehandler('aevt', 'quit', self.quit)
+                self.installaehandler('****', '****', self.other)
+                self.mainloop()
+
+        def quit(self, **args):
+                self._quit()
+
+        def open_app(self, **args):
+                pass
+
+        def other(self, _object=None, _class=None, _type=None, **args):
+                print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
+
 
 if __name__ == '__main__':
-	_Test()
+        _Test()
diff --git a/Lib/plat-mac/argvemulator.py b/Lib/plat-mac/argvemulator.py
index 5fad8d4..0516695 100644
--- a/Lib/plat-mac/argvemulator.py
+++ b/Lib/plat-mac/argvemulator.py
@@ -11,104 +11,104 @@
 import aetools
 
 class ArgvCollector:
-	
-	"""A minimal FrameWork.Application-like class"""
-	
-	def __init__(self):
-		self.quitting = 0
-		self.ae_handlers = {}
-		# Remove the funny -psn_xxx_xxx argument
-		if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn':
-			del sys.argv[1]
-		self.installaehandler('aevt', 'oapp', self.open_app)
-		self.installaehandler('aevt', 'odoc', self.open_file)
-	
-	def installaehandler(self, classe, type, callback):
-		AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
-		self.ae_handlers[(classe, type)] = callback
-	
-	def close(self):
-		for classe, type in self.ae_handlers.keys():
-			AE.AERemoveEventHandler(classe, type)
-	
-	def mainloop(self, mask = highLevelEventMask, timeout = 1*60):
-		stoptime = Evt.TickCount() + timeout
-		while not self.quitting and Evt.TickCount() < stoptime:
-			self.dooneevent(mask, timeout)
-		self.close()
-	
-	def _quit(self):
-		self.quitting = 1
-	
-	def dooneevent(self, mask = highLevelEventMask, timeout = 1*60):
-		got, event = Evt.WaitNextEvent(mask, timeout)
-		if got:
-			self.lowlevelhandler(event)
-	
-	def lowlevelhandler(self, event):
-		what, message, when, where, modifiers = event
-		h, v = where
-		if what == kHighLevelEvent:
-			try:
-				AE.AEProcessAppleEvent(event)
-			except AE.Error, err:
-				msg = "High Level Event: %s %s" % \
-					(`hex(message)`, `hex(h | (v<<16))`)
-				print 'AE error: ', err
-				print 'in', msg
-				traceback.print_exc()
-			return
-		else:
-			print "Unhandled event:", event
 
-	def callback_wrapper(self, _request, _reply):
-		_parameters, _attributes = aetools.unpackevent(_request)
-		_class = _attributes['evcl'].type
-		_type = _attributes['evid'].type
-		
-		if self.ae_handlers.has_key((_class, _type)):
-			_function = self.ae_handlers[(_class, _type)]
-		elif self.ae_handlers.has_key((_class, '****')):
-			_function = self.ae_handlers[(_class, '****')]
-		elif self.ae_handlers.has_key(('****', '****')):
-			_function = self.ae_handlers[('****', '****')]
-		else:
-			raise 'Cannot happen: AE callback without handler', (_class, _type)
-		
-		# XXXX Do key-to-name mapping here
-		
-		_parameters['_attributes'] = _attributes
-		_parameters['_class'] = _class
-		_parameters['_type'] = _type
-		if _parameters.has_key('----'):
-			_object = _parameters['----']
-			del _parameters['----']
-			# The try/except that used to be here can mask programmer errors.
-			# Let the program crash, the programmer can always add a **args
-			# to the formal parameter list.
-			rv = apply(_function, (_object,), _parameters)
-		else:
-			#Same try/except comment as above
-			rv = apply(_function, (), _parameters)
-		
-		if rv == None:
-			aetools.packevent(_reply, {})
-		else:
-			aetools.packevent(_reply, {'----':rv})
+        """A minimal FrameWork.Application-like class"""
 
-	def open_app(self, **args):
-		self._quit()
-		
-	def open_file(self, _object=None, **args):
-		for alias in _object:
-			fsr = alias.FSResolveAlias(None)[0]
-			pathname = fsr.as_pathname()
-			sys.argv.append(pathname)
-		self._quit()
-		
-	def other(self, _object=None, _class=None, _type=None, **args):
-		print 'Ignore AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
+        def __init__(self):
+                self.quitting = 0
+                self.ae_handlers = {}
+                # Remove the funny -psn_xxx_xxx argument
+                if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn':
+                        del sys.argv[1]
+                self.installaehandler('aevt', 'oapp', self.open_app)
+                self.installaehandler('aevt', 'odoc', self.open_file)
+
+        def installaehandler(self, classe, type, callback):
+                AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
+                self.ae_handlers[(classe, type)] = callback
+
+        def close(self):
+                for classe, type in self.ae_handlers.keys():
+                        AE.AERemoveEventHandler(classe, type)
+
+        def mainloop(self, mask = highLevelEventMask, timeout = 1*60):
+                stoptime = Evt.TickCount() + timeout
+                while not self.quitting and Evt.TickCount() < stoptime:
+                        self.dooneevent(mask, timeout)
+                self.close()
+
+        def _quit(self):
+                self.quitting = 1
+
+        def dooneevent(self, mask = highLevelEventMask, timeout = 1*60):
+                got, event = Evt.WaitNextEvent(mask, timeout)
+                if got:
+                        self.lowlevelhandler(event)
+
+        def lowlevelhandler(self, event):
+                what, message, when, where, modifiers = event
+                h, v = where
+                if what == kHighLevelEvent:
+                        try:
+                                AE.AEProcessAppleEvent(event)
+                        except AE.Error, err:
+                                msg = "High Level Event: %s %s" % \
+                                        (`hex(message)`, `hex(h | (v<<16))`)
+                                print 'AE error: ', err
+                                print 'in', msg
+                                traceback.print_exc()
+                        return
+                else:
+                        print "Unhandled event:", event
+
+        def callback_wrapper(self, _request, _reply):
+                _parameters, _attributes = aetools.unpackevent(_request)
+                _class = _attributes['evcl'].type
+                _type = _attributes['evid'].type
+
+                if self.ae_handlers.has_key((_class, _type)):
+                        _function = self.ae_handlers[(_class, _type)]
+                elif self.ae_handlers.has_key((_class, '****')):
+                        _function = self.ae_handlers[(_class, '****')]
+                elif self.ae_handlers.has_key(('****', '****')):
+                        _function = self.ae_handlers[('****', '****')]
+                else:
+                        raise 'Cannot happen: AE callback without handler', (_class, _type)
+
+                # XXXX Do key-to-name mapping here
+
+                _parameters['_attributes'] = _attributes
+                _parameters['_class'] = _class
+                _parameters['_type'] = _type
+                if _parameters.has_key('----'):
+                        _object = _parameters['----']
+                        del _parameters['----']
+                        # The try/except that used to be here can mask programmer errors.
+                        # Let the program crash, the programmer can always add a **args
+                        # to the formal parameter list.
+                        rv = _function(_object, **_parameters)
+                else:
+                        #Same try/except comment as above
+                        rv = _function(**_parameters)
+
+                if rv == None:
+                        aetools.packevent(_reply, {})
+                else:
+                        aetools.packevent(_reply, {'----':rv})
+
+        def open_app(self, **args):
+                self._quit()
+
+        def open_file(self, _object=None, **args):
+                for alias in _object:
+                        fsr = alias.FSResolveAlias(None)[0]
+                        pathname = fsr.as_pathname()
+                        sys.argv.append(pathname)
+                self._quit()
+
+        def other(self, _object=None, _class=None, _type=None, **args):
+                print 'Ignore AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
 
 if __name__ == '__main__':
-	ArgvCollector().mainloop()
-	print "sys.argv=", sys.argv
+        ArgvCollector().mainloop()
+        print "sys.argv=", sys.argv
diff --git a/Lib/plat-mac/icopen.py b/Lib/plat-mac/icopen.py
index d819159..99e866e 100644
--- a/Lib/plat-mac/icopen.py
+++ b/Lib/plat-mac/icopen.py
@@ -29,7 +29,7 @@
 
 Put this file in your Python path, and create a file named {Python}:sitecustomize.py
 that contains:
-	import icopen
+        import icopen
 
 (If {Python}:sitecustomizer.py already exists, just add the 'import' line to it.)
 
@@ -42,18 +42,18 @@
 _builtin_open = globals().get('_builtin_open', __builtin__.open)
 
 def _open_with_typer(*args):
-	file = apply(_builtin_open, args)
-	filename = args[0]
-	mode = 'r'
-	if args[1:]:
-		mode = args[1]
-	if mode[0] == 'w':
-		from ic import error, settypecreator
-		try:
-			settypecreator(filename)
-		except error:
-			pass
-	return file
+        file = _builtin_open(*args)
+        filename = args[0]
+        mode = 'r'
+        if args[1:]:
+                mode = args[1]
+        if mode[0] == 'w':
+                from ic import error, settypecreator
+                try:
+                        settypecreator(filename)
+                except error:
+                        pass
+        return file
 
 __builtin__.open = _open_with_typer
 
@@ -63,4 +63,4 @@
 _open_with_typer('test.txt', 'w')
 _open_with_typer('test.html', 'w')
 _open_with_typer('test.foo', 'w')
-"""
\ No newline at end of file
+"""
diff --git a/Lib/test/reperf.py b/Lib/test/reperf.py
index 6ad9a08..68ac40f 100644
--- a/Lib/test/reperf.py
+++ b/Lib/test/reperf.py
@@ -12,7 +12,7 @@
     t0 = time.clock()
     try:
         for i in range(n):
-            result = apply(func, args, kw)
+            result = func(*args, **kw)
         return result
     finally:
         t1 = time.clock()
diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py
index f32dbf3..188da8d 100644
--- a/Lib/test/test_curses.py
+++ b/Lib/test/test_curses.py
@@ -26,7 +26,7 @@
     for meth in [stdscr.addch, stdscr.addstr]:
         for args in [('a'), ('a', curses.A_BOLD),
                      (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]:
-            apply(meth, args)
+            meth(*args)
 
     for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot,
                  stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch,
diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py
index 2ec4325..a5ebe5f 100644
--- a/Lib/xml/dom/minidom.py
+++ b/Lib/xml/dom/minidom.py
@@ -1902,7 +1902,7 @@
     return StringIO()
 
 def _do_pulldom_parse(func, args, kwargs):
-    events = apply(func, args, kwargs)
+    events = func(*args, **kwargs)
     toktype, rootNode = events.getEvent()
     events.expandNode(rootNode)
     events.clear()
@@ -1915,7 +1915,7 @@
         return expatbuilder.parse(file)
     else:
         from xml.dom import pulldom
-        return _do_pulldom_parse(pulldom.parse, (file,), 
+        return _do_pulldom_parse(pulldom.parse, (file,),
             {'parser': parser, 'bufsize': bufsize})
 
 def parseString(string, parser=None):
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 29e11e5..c280cb4 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -112,7 +112,10 @@
 \n\
 Call a callable object with positional arguments taken from the tuple args,\n\
 and keyword arguments taken from the optional dictionary kwargs.\n\
-Note that classes are callable, as are instances with a __call__() method.");
+Note that classes are callable, as are instances with a __call__() method.\n\
+\n\
+Deprecated since release 2.3. Instead, use the extended call syntax:\n\
+    function(*args, **keywords).");
 
 
 static PyObject *
